blob: 3c6802f8a6a79d1097f8eabc939cf954f5a713f1 [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;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800152 static final boolean DEBUG_ADD_REMOVE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_FOCUS = false;
154 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800155 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800156 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static final boolean DEBUG_LAYERS = false;
158 static final boolean DEBUG_INPUT = false;
159 static final boolean DEBUG_INPUT_METHOD = false;
160 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700161 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800162 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700164 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_APP_TRANSITIONS = false;
166 static final boolean DEBUG_STARTING_WINDOW = false;
167 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700168 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800169 static final boolean DEBUG_DRAG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700171 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 static final boolean PROFILE_ORIENTATION = false;
174 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700175 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 /** How much to multiply the policy's type layer, to reserve room
178 * for multiple windows of the same type and Z-ordering adjustment
179 * with TYPE_LAYER_OFFSET. */
180 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
183 * or below others in the same layer. */
184 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 /** How much to increment the layer for each window, to reserve room
187 * for effect surfaces between them.
188 */
189 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 /** The maximum length we will accept for a loaded animation duration:
192 * this is 10 seconds.
193 */
194 static final int MAX_ANIMATION_DURATION = 10*1000;
195
196 /** Amount of time (in milliseconds) to animate the dim surface from one
197 * value to another, when no window animation is driving it.
198 */
199 static final int DEFAULT_DIM_DURATION = 200;
200
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700201 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
202 * compatible windows.
203 */
204 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
205
Dianne Hackborna1111872010-11-23 20:55:11 -0800206 /**
207 * If true, the window manager will do its own custom freezing and general
208 * management of the screen during rotation.
209 */
210 static final boolean CUSTOM_SCREEN_ROTATION = true;
211
Jeff Brown7fbdc842010-06-17 20:52:56 -0700212 // Maximum number of milliseconds to wait for input event injection.
213 // FIXME is this value reasonable?
214 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brownb09abc12011-01-13 21:08:27 -0800215
216 // Maximum number of milliseconds to wait for input devices to be enumerated before
217 // proceding with safe mode detection.
218 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700219
220 // Default input dispatching timeout in nanoseconds.
221 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 static final int UPDATE_FOCUS_NORMAL = 0;
224 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
225 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
226 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700229 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230
231 /**
232 * Condition waited on by {@link #reenableKeyguard} to know the call to
233 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500234 * This is set to true only if mKeyguardTokenWatcher.acquired() has
235 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500237 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238
Jim Miller284b62e2010-06-08 14:27:42 -0700239 private static final int ALLOW_DISABLE_YES = 1;
240 private static final int ALLOW_DISABLE_NO = 0;
241 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
242 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
243
Mike Lockwood983ee092009-11-22 01:42:24 -0500244 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
245 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700247 if (shouldAllowDisableKeyguard()) {
248 mPolicy.enableKeyguard(false);
249 mKeyguardDisabled = true;
250 } else {
251 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 }
254 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700255 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500256 synchronized (mKeyguardTokenWatcher) {
257 mKeyguardDisabled = false;
258 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 }
260 }
261 };
262
Jim Miller284b62e2010-06-08 14:27:42 -0700263 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
264 @Override
265 public void onReceive(Context context, Intent intent) {
266 mPolicy.enableKeyguard(true);
267 synchronized(mKeyguardTokenWatcher) {
268 // lazily evaluate this next time we're asked to disable keyguard
269 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
270 mKeyguardDisabled = false;
271 }
272 }
273 };
274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 final Context mContext;
276
277 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
282
283 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 /**
288 * All currently active sessions with clients.
289 */
290 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 /**
293 * Mapping from an IWindow IBinder to the server's Window object.
294 * This is also used as the lock for all of our state.
295 */
296 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
297
298 /**
299 * Mapping from a token IBinder to a WindowToken object.
300 */
301 final HashMap<IBinder, WindowToken> mTokenMap =
302 new HashMap<IBinder, WindowToken>();
303
304 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 * 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
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800313 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 */
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 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800347 * Used when processing mPendingRemove to avoid working on the original array.
348 */
349 WindowState[] mPendingRemoveTmp = new WindowState[20];
350
351 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 * Windows whose surface should be destroyed.
353 */
354 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
355
356 /**
357 * Windows that have lost input focus and are waiting for the new
358 * focus window to be displayed before they are told about this.
359 */
360 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
361
362 /**
363 * This is set when we have run out of memory, and will either be an empty
364 * list or contain windows that need to be force removed.
365 */
366 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700367
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800368 /**
369 * Used when rebuilding window list to keep track of windows that have
370 * been removed.
371 */
372 WindowState[] mRebuildTmp = new WindowState[20];
373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700377 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 Surface mBlurSurface;
379 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700380 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800381 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800382 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 final float[] mTmpFloats = new float[9];
387
388 boolean mSafeMode;
389 boolean mDisplayEnabled = false;
390 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700391 int mInitialDisplayWidth = 0;
392 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 int mRotation = 0;
394 int mRequestedRotation = 0;
395 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700396 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 ArrayList<IRotationWatcher> mRotationWatchers
398 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 boolean mLayoutNeeded = true;
401 boolean mAnimationPending = false;
402 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800403 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 boolean mWindowsFreezingScreen = false;
405 long mFreezeGcPending = 0;
406 int mAppsFreezingScreen = 0;
407
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800408 int mLayoutSeq = 0;
409
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800410 // State while inside of layoutAndPlaceSurfacesLocked().
411 boolean mFocusMayChange;
412
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800413 Configuration mCurConfiguration = new Configuration();
414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 // This is held as long as we have the screen frozen, to give us time to
416 // perform a rotation animation when turning off shows the lock screen which
417 // changes the orientation.
418 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 // State management of app transitions. When we are preparing for a
421 // transition, mNextAppTransition will be the kind of transition to
422 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
423 // mOpeningApps and mClosingApps are the lists of tokens that will be
424 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700425 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700426 String mNextAppTransitionPackage;
427 int mNextAppTransitionEnter;
428 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700430 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 boolean mAppTransitionTimeout = false;
432 boolean mStartingIconInTransition = false;
433 boolean mSkipAppTransitionAnimation = false;
434 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
435 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700436 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
437 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 H mH = new H();
442
443 WindowState mCurrentFocus = null;
444 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 // This just indicates the window the input method is on top of, not
447 // necessarily the window its input is going to.
448 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 boolean mInputMethodTargetWaitingAnim;
450 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 WindowState mInputMethodWindow = null;
453 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
454
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700455 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800456
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700457 // If non-null, this is the currently visible window that is associated
458 // with the wallpaper.
459 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700460 // If non-null, we are in the middle of animating from one wallpaper target
461 // to another, and this is the lower one in Z-order.
462 WindowState mLowerWallpaperTarget = null;
463 // If non-null, we are in the middle of animating from one wallpaper target
464 // to another, and this is the higher one in Z-order.
465 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800466 // Window currently running an animation that has requested it be detached
467 // from the wallpaper. This means we need to ensure the wallpaper is
468 // visible behind it in case it animates in a way that would allow it to be
469 // seen.
470 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700471 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700472 float mLastWallpaperX = -1;
473 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800474 float mLastWallpaperXStep = -1;
475 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700476 // This is set when we are waiting for a wallpaper to tell us it is done
477 // changing its scroll position.
478 WindowState mWaitingOnWallpaper;
479 // The last time we had a timeout when waiting for a wallpaper.
480 long mLastWallpaperTimeoutTime;
481 // We give a wallpaper up to 150ms to finish scrolling.
482 static final long WALLPAPER_TIMEOUT = 150;
483 // Time we wait after a timeout before trying to wait again.
484 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 AppWindowToken mFocusedApp = null;
487
488 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 float mWindowAnimationScale = 1.0f;
491 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700492
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700493 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494
495 // Who is holding the screen on.
496 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700497 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700498
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700499 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700502 * Drag/drop state
503 */
504 class DragState {
505 IBinder mToken;
506 Surface mSurface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800507 int mFlags;
Chris Tate7b362e42010-11-04 16:02:52 -0700508 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700509 ClipData mData;
510 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700511 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700512 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700513 float mThumbOffsetX, mThumbOffsetY;
514 InputChannel mServerChannel, mClientChannel;
515 WindowState mTargetWindow;
516 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700517 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700518
Christopher Tateccd24de2011-01-12 15:02:55 -0800519 boolean mPerformDeferredRotation;
520 int mRotation;
521 int mAnimFlags;
522
Christopher Tatea53146c2010-09-07 11:57:52 -0700523 private final Rect tmpRect = new Rect();
524
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800525 DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700526 mToken = token;
527 mSurface = surface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800528 mFlags = flags;
Chris Tate7b362e42010-11-04 16:02:52 -0700529 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700530 mNotifiedWindows = new ArrayList<WindowState>();
531 }
532
533 void reset() {
534 if (mSurface != null) {
535 mSurface.destroy();
536 }
537 mSurface = null;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800538 mFlags = 0;
Chris Tate7b362e42010-11-04 16:02:52 -0700539 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700540 mToken = null;
541 mData = null;
542 mThumbOffsetX = mThumbOffsetY = 0;
543 mNotifiedWindows = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800544 mPerformDeferredRotation = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700545 }
546
547 void register() {
548 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
549 if (mClientChannel != null) {
550 Slog.e(TAG, "Duplicate register of drag input channel");
551 } else {
552 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
553 mServerChannel = channels[0];
554 mClientChannel = channels[1];
Jeff Brown928e0542011-01-10 11:17:36 -0800555 mInputManager.registerInputChannel(mServerChannel, null);
Christopher Tatea53146c2010-09-07 11:57:52 -0700556 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
557 mH.getLooper().getQueue());
558 }
559 }
560
561 void unregister() {
562 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
563 if (mClientChannel == null) {
564 Slog.e(TAG, "Unregister of nonexistent drag input channel");
565 } else {
566 mInputManager.unregisterInputChannel(mServerChannel);
567 InputQueue.unregisterInputChannel(mClientChannel);
568 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700569 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700570 mClientChannel = null;
571 mServerChannel = null;
572 }
573 }
574
Chris Tatea32dcf72010-10-14 12:13:50 -0700575 int getDragLayerLw() {
576 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
577 * TYPE_LAYER_MULTIPLIER
578 + TYPE_LAYER_OFFSET;
579 }
580
Christopher Tatea53146c2010-09-07 11:57:52 -0700581 /* call out to each visible window/session informing it about the drag
582 */
Chris Tateb8203e92010-10-12 14:23:21 -0700583 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700584 // Cache a base-class instance of the clip metadata so that parceling
585 // works correctly in calling out to the apps.
Dianne Hackbornf834dfa2010-10-26 12:43:57 -0700586 mDataDescription = mData.getDescription();
Christopher Tatea53146c2010-09-07 11:57:52 -0700587 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700588 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700589
590 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700591 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700592 }
593
Christopher Tate2c095f32010-10-04 14:13:40 -0700594 final int N = mWindows.size();
595 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700596 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700597 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700598 }
599
600 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
601 * designated window is potentially a drop recipient. There are race situations
602 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
603 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700604 *
605 * This method clones the 'event' parameter if it's being delivered to the same
606 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700607 */
Chris Tateb478f462010-10-15 16:02:26 -0700608 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
609 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700610 // Don't actually send the event if the drag is supposed to be pinned
611 // to the originating window but 'newWin' is not that window.
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800612 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700613 final IBinder winBinder = newWin.mClient.asBinder();
614 if (winBinder != mLocalWin) {
615 if (DEBUG_DRAG) {
616 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
617 }
618 return;
619 }
620 }
621
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700622 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700623 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
624 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800625 null, desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700626 try {
627 newWin.mClient.dispatchDragEvent(event);
628 // track each window that we've notified that the drag is starting
629 mNotifiedWindows.add(newWin);
630 } catch (RemoteException e) {
631 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700632 } finally {
633 // if the callee was local, the dispatch has already recycled the event
634 if (Process.myPid() != newWin.mSession.mPid) {
635 event.recycle();
636 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700637 }
638 }
639 }
640
641 /* helper - construct and send a DRAG_STARTED event only if the window has not
642 * previously been notified, i.e. it became visible after the drag operation
643 * was begun. This is a rare case.
644 */
645 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700646 if (mDragInProgress) {
647 // If we have sent the drag-started, we needn't do so again
648 for (WindowState ws : mNotifiedWindows) {
649 if (ws == newWin) {
650 return;
651 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700652 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700653 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700654 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700655 }
Chris Tateb478f462010-10-15 16:02:26 -0700656 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700657 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700658 }
659
Chris Tated4533f142010-10-19 15:15:08 -0700660 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700661 if (DEBUG_DRAG) {
662 Slog.d(TAG, "broadcasting DRAG_ENDED");
663 }
Chris Tated4533f142010-10-19 15:15:08 -0700664 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
Christopher Tate407b4e92010-11-30 17:14:08 -0800665 0, 0, null, null, null, mDragResult);
Chris Tated4533f142010-10-19 15:15:08 -0700666 for (WindowState ws: mNotifiedWindows) {
667 try {
668 ws.mClient.dispatchDragEvent(evt);
669 } catch (RemoteException e) {
670 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700671 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700672 }
Chris Tated4533f142010-10-19 15:15:08 -0700673 mNotifiedWindows.clear();
674 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700675 evt.recycle();
676 }
677
Chris Tated4533f142010-10-19 15:15:08 -0700678 void endDragLw() {
679 mDragState.broadcastDragEndedLw();
680
681 // stop intercepting input
682 mDragState.unregister();
683 mInputMonitor.updateInputWindowsLw();
684
Christopher Tateccd24de2011-01-12 15:02:55 -0800685 // Retain the parameters of any deferred rotation operation so
686 // that we can perform it after the reset / unref of the drag state
687 final boolean performRotation = mPerformDeferredRotation;
688 final int rotation = mRotation;
689 final int animFlags = mAnimFlags;
690
Chris Tated4533f142010-10-19 15:15:08 -0700691 // free our resources and drop all the object references
692 mDragState.reset();
693 mDragState = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800694
695 // Now that we've officially ended the drag, execute any
696 // deferred rotation
697 if (performRotation) {
698 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
699 boolean changed = setRotationUncheckedLocked(rotation, animFlags);
700 if (changed) {
701 sendNewConfiguration();
702 }
703 }
Chris Tated4533f142010-10-19 15:15:08 -0700704 }
705
Christopher Tatea53146c2010-09-07 11:57:52 -0700706 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700707 final int myPid = Process.myPid();
708
709 // Move the surface to the given touch
710 mSurface.openTransaction();
711 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
712 mSurface.closeTransaction();
713
714 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700715 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800716 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700717 final IBinder touchedBinder = touchedWin.mClient.asBinder();
718 if (touchedBinder != mLocalWin) {
719 // This drag is pinned only to the originating window, but the drag
720 // point is outside that window. Pretend it's over empty space.
721 touchedWin = null;
722 }
723 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700724 try {
725 // have we dragged over a new window?
726 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
727 if (DEBUG_DRAG) {
728 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
729 }
730 // force DRAG_EXITED_EVENT if appropriate
731 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700732 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800733 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700734 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700735 if (myPid != mTargetWindow.mSession.mPid) {
736 evt.recycle();
737 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700738 }
739 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700740 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700741 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
742 }
743 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700744 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800745 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700746 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700747 if (myPid != touchedWin.mSession.mPid) {
748 evt.recycle();
749 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700750 }
751 } catch (RemoteException e) {
752 Slog.w(TAG, "can't send drag notification to windows");
753 }
754 mTargetWindow = touchedWin;
755 }
756
Chris Tated4533f142010-10-19 15:15:08 -0700757 // Tell the drop target about the data. Returns 'true' if we can immediately
758 // dispatch the global drag-ended message, 'false' if we need to wait for a
759 // result from the recipient.
760 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700761 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700762 if (touchedWin == null) {
763 // "drop" outside a valid window -- no recipient to apply a
764 // timeout to, and we can send the drag-ended message immediately.
765 mDragResult = false;
766 return true;
767 }
768
769 if (DEBUG_DRAG) {
770 Slog.d(TAG, "sending DROP to " + touchedWin);
771 }
772 final int myPid = Process.myPid();
773 final IBinder token = touchedWin.mClient.asBinder();
774 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
775 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800776 null, null, mData, false);
Chris Tated4533f142010-10-19 15:15:08 -0700777 try {
778 touchedWin.mClient.dispatchDragEvent(evt);
779
780 // 5 second timeout for this window to respond to the drop
781 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
782 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
783 mH.sendMessageDelayed(msg, 5000);
784 } catch (RemoteException e) {
785 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
786 return true;
787 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700788 if (myPid != touchedWin.mSession.mPid) {
789 evt.recycle();
790 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700791 }
Chris Tated4533f142010-10-19 15:15:08 -0700792 mToken = token;
793 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700794 }
795
796 // Find the visible, touch-deliverable window under the given point
797 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
798 WindowState touchedWin = null;
799 final int x = (int) xf;
800 final int y = (int) yf;
801 final ArrayList<WindowState> windows = mWindows;
802 final int N = windows.size();
803 for (int i = N - 1; i >= 0; i--) {
804 WindowState child = windows.get(i);
805 final int flags = child.mAttrs.flags;
806 if (!child.isVisibleLw()) {
807 // not visible == don't tell about drags
808 continue;
809 }
810 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
811 // not touchable == don't tell about drags
812 continue;
813 }
814 // account for the window's decor etc
815 tmpRect.set(child.mFrame);
816 if (child.mTouchableInsets == ViewTreeObserver
817 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
818 // The point is inside of the window if it is
819 // inside the frame, AND the content part of that
820 // frame that was given by the application.
821 tmpRect.left += child.mGivenContentInsets.left;
822 tmpRect.top += child.mGivenContentInsets.top;
823 tmpRect.right -= child.mGivenContentInsets.right;
824 tmpRect.bottom -= child.mGivenContentInsets.bottom;
825 } else if (child.mTouchableInsets == ViewTreeObserver
826 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
827 // The point is inside of the window if it is
828 // inside the frame, AND the visible part of that
829 // frame that was given by the application.
830 tmpRect.left += child.mGivenVisibleInsets.left;
831 tmpRect.top += child.mGivenVisibleInsets.top;
832 tmpRect.right -= child.mGivenVisibleInsets.right;
833 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
834 }
835 final int touchFlags = flags &
836 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
837 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
838 if (tmpRect.contains(x, y) || touchFlags == 0) {
839 // Found it
840 touchedWin = child;
841 break;
842 }
843 }
844
845 return touchedWin;
846 }
Christopher Tateccd24de2011-01-12 15:02:55 -0800847
848 void setDeferredRotation(int rotation, int animFlags) {
849 mRotation = rotation;
850 mAnimFlags = animFlags;
851 mPerformDeferredRotation = true;
852 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700853 }
854
855 DragState mDragState = null;
856 private final InputHandler mDragInputHandler = new BaseInputHandler() {
857 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700858 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
859 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700860 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700861 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
862 && mDragState != null) {
863 boolean endDrag = false;
864 final float newX = event.getRawX();
865 final float newY = event.getRawY();
866
Christopher Tatea53146c2010-09-07 11:57:52 -0700867 switch (event.getAction()) {
868 case MotionEvent.ACTION_DOWN: {
869 if (DEBUG_DRAG) {
870 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
871 }
872 } break;
873
874 case MotionEvent.ACTION_MOVE: {
875 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700876 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700877 mDragState.notifyMoveLw(newX, newY);
878 }
879 } break;
880
881 case MotionEvent.ACTION_UP: {
882 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
883 + newX + "," + newY);
884 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700885 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700886 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700887 } break;
888
889 case MotionEvent.ACTION_CANCEL: {
890 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
891 endDrag = true;
892 } break;
893 }
894
895 if (endDrag) {
896 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
897 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700898 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700899 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700900 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700901 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700902
903 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700904 }
905 } catch (Exception e) {
906 Slog.e(TAG, "Exception caught by drag handleMotion", e);
907 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700908 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700909 }
910 }
911 };
912
913 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 * Whether the UI is currently running in touch mode (not showing
915 * navigational focus because the user is directly pressing the screen).
916 */
917 boolean mInTouchMode = false;
918
919 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700920 private ArrayList<WindowChangeListener> mWindowChangeListeners =
921 new ArrayList<WindowChangeListener>();
922 private boolean mWindowsChanged = false;
923
924 public interface WindowChangeListener {
925 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700926 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928
Dianne Hackbornc485a602009-03-24 22:39:49 -0700929 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700930 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700931
932 // The frame use to limit the size of the app running in compatibility mode.
933 Rect mCompatibleScreenFrame = new Rect();
934 // The surface used to fill the outer rim of the app running in compatibility mode.
935 Surface mBackgroundFillerSurface = null;
936 boolean mBackgroundFillerShown = false;
937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 public static WindowManagerService main(Context context,
939 PowerManagerService pm, boolean haveInputMethods) {
940 WMThread thr = new WMThread(context, pm, haveInputMethods);
941 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 synchronized (thr) {
944 while (thr.mService == null) {
945 try {
946 thr.wait();
947 } catch (InterruptedException e) {
948 }
949 }
950 }
Romain Guy06882f82009-06-10 13:36:04 -0700951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 return thr.mService;
953 }
Romain Guy06882f82009-06-10 13:36:04 -0700954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 static class WMThread extends Thread {
956 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 private final Context mContext;
959 private final PowerManagerService mPM;
960 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 public WMThread(Context context, PowerManagerService pm,
963 boolean haveInputMethods) {
964 super("WindowManager");
965 mContext = context;
966 mPM = pm;
967 mHaveInputMethods = haveInputMethods;
968 }
Romain Guy06882f82009-06-10 13:36:04 -0700969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 public void run() {
971 Looper.prepare();
972 WindowManagerService s = new WindowManagerService(mContext, mPM,
973 mHaveInputMethods);
974 android.os.Process.setThreadPriority(
975 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700976 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 synchronized (this) {
979 mService = s;
980 notifyAll();
981 }
Romain Guy06882f82009-06-10 13:36:04 -0700982
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700983 // For debug builds, log event loop stalls to dropbox for analysis.
984 if (StrictMode.conditionallyEnableDebugLogging()) {
985 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
986 }
987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 Looper.loop();
989 }
990 }
991
992 static class PolicyThread extends Thread {
993 private final WindowManagerPolicy mPolicy;
994 private final WindowManagerService mService;
995 private final Context mContext;
996 private final PowerManagerService mPM;
997 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 public PolicyThread(WindowManagerPolicy policy,
1000 WindowManagerService service, Context context,
1001 PowerManagerService pm) {
1002 super("WindowManagerPolicy");
1003 mPolicy = policy;
1004 mService = service;
1005 mContext = context;
1006 mPM = pm;
1007 }
Romain Guy06882f82009-06-10 13:36:04 -07001008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 public void run() {
1010 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -08001011 WindowManagerPolicyThread.set(this, Looper.myLooper());
1012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -08001014 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 android.os.Process.setThreadPriority(
1016 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001017 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -07001019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 synchronized (this) {
1021 mRunning = true;
1022 notifyAll();
1023 }
Romain Guy06882f82009-06-10 13:36:04 -07001024
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001025 // For debug builds, log event loop stalls to dropbox for analysis.
1026 if (StrictMode.conditionallyEnableDebugLogging()) {
1027 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
1028 }
1029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 Looper.loop();
1031 }
1032 }
1033
1034 private WindowManagerService(Context context, PowerManagerService pm,
1035 boolean haveInputMethods) {
1036 mContext = context;
1037 mHaveInputMethods = haveInputMethods;
1038 mLimitedAlphaCompositing = context.getResources().getBoolean(
1039 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -07001040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 mPowerManager = pm;
1042 mPowerManager.setPolicy(mPolicy);
1043 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1044 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1045 "SCREEN_FROZEN");
1046 mScreenFrozenLock.setReferenceCounted(false);
1047
1048 mActivityManager = ActivityManagerNative.getDefault();
1049 mBatteryStats = BatteryStatsService.getService();
1050
1051 // Get persisted window scale setting
1052 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1053 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1054 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1055 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001056
Jim Miller284b62e2010-06-08 14:27:42 -07001057 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1058 IntentFilter filter = new IntentFilter();
1059 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1060 mContext.registerReceiver(mBroadcastReceiver, filter);
1061
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001062 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1063 "KEEP_SCREEN_ON_FLAG");
1064 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065
Jeff Browne33348b2010-07-15 23:54:05 -07001066 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1069 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071 synchronized (thr) {
1072 while (!thr.mRunning) {
1073 try {
1074 thr.wait();
1075 } catch (InterruptedException e) {
1076 }
1077 }
1078 }
Romain Guy06882f82009-06-10 13:36:04 -07001079
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001080 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 // Add ourself to the Watchdog monitors.
1083 Watchdog.getInstance().addMonitor(this);
1084 }
1085
1086 @Override
1087 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1088 throws RemoteException {
1089 try {
1090 return super.onTransact(code, data, reply, flags);
1091 } catch (RuntimeException e) {
1092 // The window manager only throws security exceptions, so let's
1093 // log all others.
1094 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001095 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 }
1097 throw e;
1098 }
1099 }
1100
Jeff Browne33348b2010-07-15 23:54:05 -07001101 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001103 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 TAG, "Adding window " + window + " at "
1105 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1106 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001107 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 }
1109
Jeff Browne33348b2010-07-15 23:54:05 -07001110 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001112 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 TAG, "Adding window " + window + " at "
1114 + i + " of " + mWindows.size() + " (before " + pos + ")");
1115 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001116 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
1118
1119 //This method finds out the index of a window that has the same app token as
1120 //win. used for z ordering the windows in mWindows
1121 private int findIdxBasedOnAppTokens(WindowState win) {
1122 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001123 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 int jmax = localmWindows.size();
1125 if(jmax == 0) {
1126 return -1;
1127 }
1128 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001129 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 if(wentry.mAppToken == win.mAppToken) {
1131 return j;
1132 }
1133 }
1134 return -1;
1135 }
Romain Guy06882f82009-06-10 13:36:04 -07001136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1138 final IWindow client = win.mClient;
1139 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001140 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 final int N = localmWindows.size();
1143 final WindowState attached = win.mAttachedWindow;
1144 int i;
1145 if (attached == null) {
1146 int tokenWindowsPos = token.windows.size();
1147 if (token.appWindowToken != null) {
1148 int index = tokenWindowsPos-1;
1149 if (index >= 0) {
1150 // If this application has existing windows, we
1151 // simply place the new window on top of them... but
1152 // keep the starting window on top.
1153 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1154 // Base windows go behind everything else.
1155 placeWindowBefore(token.windows.get(0), win);
1156 tokenWindowsPos = 0;
1157 } else {
1158 AppWindowToken atoken = win.mAppToken;
1159 if (atoken != null &&
1160 token.windows.get(index) == atoken.startingWindow) {
1161 placeWindowBefore(token.windows.get(index), win);
1162 tokenWindowsPos--;
1163 } else {
1164 int newIdx = findIdxBasedOnAppTokens(win);
1165 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001166 //there is a window above this one associated with the same
1167 //apptoken note that the window could be a floating window
1168 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001170 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1171 Slog.v(TAG, "Adding window " + win + " at "
1172 + (newIdx+1) + " of " + N);
1173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001175 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 }
1178 }
1179 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001180 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 TAG, "Figuring out where to add app window "
1182 + client.asBinder() + " (token=" + token + ")");
1183 // Figure out where the window should go, based on the
1184 // order of applications.
1185 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001186 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 for (i=NA-1; i>=0; i--) {
1188 AppWindowToken t = mAppTokens.get(i);
1189 if (t == token) {
1190 i--;
1191 break;
1192 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001193
Dianne Hackborna8f60182009-09-01 19:01:50 -07001194 // We haven't reached the token yet; if this token
1195 // is not going to the bottom and has windows, we can
1196 // use it as an anchor for when we do reach the token.
1197 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 pos = t.windows.get(0);
1199 }
1200 }
1201 // We now know the index into the apps. If we found
1202 // an app window above, that gives us the position; else
1203 // we need to look some more.
1204 if (pos != null) {
1205 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001206 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 if (atoken != null) {
1208 final int NC = atoken.windows.size();
1209 if (NC > 0) {
1210 WindowState bottom = atoken.windows.get(0);
1211 if (bottom.mSubLayer < 0) {
1212 pos = bottom;
1213 }
1214 }
1215 }
1216 placeWindowBefore(pos, win);
1217 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001218 // Continue looking down until we find the first
1219 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 while (i >= 0) {
1221 AppWindowToken t = mAppTokens.get(i);
1222 final int NW = t.windows.size();
1223 if (NW > 0) {
1224 pos = t.windows.get(NW-1);
1225 break;
1226 }
1227 i--;
1228 }
1229 if (pos != null) {
1230 // Move in front of any windows attached to this
1231 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001232 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 if (atoken != null) {
1234 final int NC = atoken.windows.size();
1235 if (NC > 0) {
1236 WindowState top = atoken.windows.get(NC-1);
1237 if (top.mSubLayer >= 0) {
1238 pos = top;
1239 }
1240 }
1241 }
1242 placeWindowAfter(pos, win);
1243 } else {
1244 // Just search for the start of this layer.
1245 final int myLayer = win.mBaseLayer;
1246 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001247 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 if (w.mBaseLayer > myLayer) {
1249 break;
1250 }
1251 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001252 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1253 Slog.v(TAG, "Adding window " + win + " at "
1254 + i + " of " + N);
1255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001257 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 }
1259 }
1260 }
1261 } else {
1262 // Figure out where window should go, based on layer.
1263 final int myLayer = win.mBaseLayer;
1264 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001265 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 i++;
1267 break;
1268 }
1269 }
1270 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001271 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001272 TAG, "Adding window " + win + " at "
1273 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001275 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 }
1277 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001278 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 token.windows.add(tokenWindowsPos, win);
1280 }
1281
1282 } else {
1283 // Figure out this window's ordering relative to the window
1284 // it is attached to.
1285 final int NA = token.windows.size();
1286 final int sublayer = win.mSubLayer;
1287 int largestSublayer = Integer.MIN_VALUE;
1288 WindowState windowWithLargestSublayer = null;
1289 for (i=0; i<NA; i++) {
1290 WindowState w = token.windows.get(i);
1291 final int wSublayer = w.mSubLayer;
1292 if (wSublayer >= largestSublayer) {
1293 largestSublayer = wSublayer;
1294 windowWithLargestSublayer = w;
1295 }
1296 if (sublayer < 0) {
1297 // For negative sublayers, we go below all windows
1298 // in the same sublayer.
1299 if (wSublayer >= sublayer) {
1300 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001301 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 token.windows.add(i, win);
1303 }
1304 placeWindowBefore(
1305 wSublayer >= 0 ? attached : w, win);
1306 break;
1307 }
1308 } else {
1309 // For positive sublayers, we go above all windows
1310 // in the same sublayer.
1311 if (wSublayer > sublayer) {
1312 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001313 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 token.windows.add(i, win);
1315 }
1316 placeWindowBefore(w, win);
1317 break;
1318 }
1319 }
1320 }
1321 if (i >= NA) {
1322 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001323 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 token.windows.add(win);
1325 }
1326 if (sublayer < 0) {
1327 placeWindowBefore(attached, win);
1328 } else {
1329 placeWindowAfter(largestSublayer >= 0
1330 ? windowWithLargestSublayer
1331 : attached,
1332 win);
1333 }
1334 }
1335 }
Romain Guy06882f82009-06-10 13:36:04 -07001336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 if (win.mAppToken != null && addToToken) {
1338 win.mAppToken.allAppWindows.add(win);
1339 }
1340 }
Romain Guy06882f82009-06-10 13:36:04 -07001341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 static boolean canBeImeTarget(WindowState w) {
1343 final int fl = w.mAttrs.flags
1344 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1345 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1346 return w.isVisibleOrAdding();
1347 }
1348 return false;
1349 }
Romain Guy06882f82009-06-10 13:36:04 -07001350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001352 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 final int N = localmWindows.size();
1354 WindowState w = null;
1355 int i = N;
1356 while (i > 0) {
1357 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001358 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001359
Joe Onorato8a9b2202010-02-26 18:56:32 -08001360 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 // + Integer.toHexString(w.mAttrs.flags));
1362 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001363 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 // Yet more tricksyness! If this window is a "starting"
1366 // window, we do actually want to be on top of it, but
1367 // it is not -really- where input will go. So if the caller
1368 // is not actually looking to move the IME, look down below
1369 // for a real window to target...
1370 if (!willMove
1371 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1372 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001373 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1375 i--;
1376 w = wb;
1377 }
1378 }
1379 break;
1380 }
1381 }
Romain Guy06882f82009-06-10 13:36:04 -07001382
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001383 // Now, a special case -- if the last target's window is in the
1384 // process of exiting, and is above the new target, keep on the
1385 // last target to avoid flicker. Consider for example a Dialog with
1386 // the IME shown: when the Dialog is dismissed, we want to keep
1387 // the IME above it until it is completely gone so it doesn't drop
1388 // behind the dialog or its full-screen scrim.
1389 if (mInputMethodTarget != null && w != null
1390 && mInputMethodTarget.isDisplayedLw()
1391 && mInputMethodTarget.mExiting) {
1392 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1393 w = mInputMethodTarget;
1394 i = localmWindows.indexOf(w);
1395 }
1396 }
Romain Guy06882f82009-06-10 13:36:04 -07001397
Joe Onorato8a9b2202010-02-26 18:56:32 -08001398 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 if (willMove && w != null) {
1402 final WindowState curTarget = mInputMethodTarget;
1403 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 // Now some fun for dealing with window animations that
1406 // modify the Z order. We need to look at all windows below
1407 // the current target that are in this app, finding the highest
1408 // visible one in layering.
1409 AppWindowToken token = curTarget.mAppToken;
1410 WindowState highestTarget = null;
1411 int highestPos = 0;
1412 if (token.animating || token.animation != null) {
1413 int pos = 0;
1414 pos = localmWindows.indexOf(curTarget);
1415 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001416 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 if (win.mAppToken != token) {
1418 break;
1419 }
1420 if (!win.mRemoved) {
1421 if (highestTarget == null || win.mAnimLayer >
1422 highestTarget.mAnimLayer) {
1423 highestTarget = win;
1424 highestPos = pos;
1425 }
1426 }
1427 pos--;
1428 }
1429 }
Romain Guy06882f82009-06-10 13:36:04 -07001430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001432 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 + mNextAppTransition + " " + highestTarget
1434 + " animating=" + highestTarget.isAnimating()
1435 + " layer=" + highestTarget.mAnimLayer
1436 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001437
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001438 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 // If we are currently setting up for an animation,
1440 // hold everything until we can find out what will happen.
1441 mInputMethodTargetWaitingAnim = true;
1442 mInputMethodTarget = highestTarget;
1443 return highestPos + 1;
1444 } else if (highestTarget.isAnimating() &&
1445 highestTarget.mAnimLayer > w.mAnimLayer) {
1446 // If the window we are currently targeting is involved
1447 // with an animation, and it is on top of the next target
1448 // we will be over, then hold off on moving until
1449 // that is done.
1450 mInputMethodTarget = highestTarget;
1451 return highestPos + 1;
1452 }
1453 }
1454 }
1455 }
Romain Guy06882f82009-06-10 13:36:04 -07001456
Joe Onorato8a9b2202010-02-26 18:56:32 -08001457 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 if (w != null) {
1459 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001460 if (DEBUG_INPUT_METHOD) {
1461 RuntimeException e = null;
1462 if (!HIDE_STACK_CRAWLS) {
1463 e = new RuntimeException();
1464 e.fillInStackTrace();
1465 }
1466 Slog.w(TAG, "Moving IM target from "
1467 + mInputMethodTarget + " to " + w, e);
1468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 mInputMethodTarget = w;
1470 if (w.mAppToken != null) {
1471 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1472 } else {
1473 setInputMethodAnimLayerAdjustment(0);
1474 }
1475 }
1476 return i+1;
1477 }
1478 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001479 if (DEBUG_INPUT_METHOD) {
1480 RuntimeException e = null;
1481 if (!HIDE_STACK_CRAWLS) {
1482 e = new RuntimeException();
1483 e.fillInStackTrace();
1484 }
1485 Slog.w(TAG, "Moving IM target from "
1486 + mInputMethodTarget + " to null", e);
1487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 mInputMethodTarget = null;
1489 setInputMethodAnimLayerAdjustment(0);
1490 }
1491 return -1;
1492 }
Romain Guy06882f82009-06-10 13:36:04 -07001493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 void addInputMethodWindowToListLocked(WindowState win) {
1495 int pos = findDesiredInputMethodWindowIndexLocked(true);
1496 if (pos >= 0) {
1497 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001498 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001499 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001501 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 moveInputMethodDialogsLocked(pos+1);
1503 return;
1504 }
1505 win.mTargetAppToken = null;
1506 addWindowToListInOrderLocked(win, true);
1507 moveInputMethodDialogsLocked(pos);
1508 }
Romain Guy06882f82009-06-10 13:36:04 -07001509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001511 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 mInputMethodAnimLayerAdjustment = adj;
1513 WindowState imw = mInputMethodWindow;
1514 if (imw != null) {
1515 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001516 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 + " anim layer: " + imw.mAnimLayer);
1518 int wi = imw.mChildWindows.size();
1519 while (wi > 0) {
1520 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001521 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001523 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 + " anim layer: " + cw.mAnimLayer);
1525 }
1526 }
1527 int di = mInputMethodDialogs.size();
1528 while (di > 0) {
1529 di --;
1530 imw = mInputMethodDialogs.get(di);
1531 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001532 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 + " anim layer: " + imw.mAnimLayer);
1534 }
1535 }
Romain Guy06882f82009-06-10 13:36:04 -07001536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1538 int wpos = mWindows.indexOf(win);
1539 if (wpos >= 0) {
1540 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001541 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001543 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 int NC = win.mChildWindows.size();
1545 while (NC > 0) {
1546 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001547 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 int cpos = mWindows.indexOf(cw);
1549 if (cpos >= 0) {
1550 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001551 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001552 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 mWindows.remove(cpos);
1554 }
1555 }
1556 }
1557 return interestingPos;
1558 }
Romain Guy06882f82009-06-10 13:36:04 -07001559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 private void reAddWindowToListInOrderLocked(WindowState win) {
1561 addWindowToListInOrderLocked(win, false);
1562 // This is a hack to get all of the child windows added as well
1563 // at the right position. Child windows should be rare and
1564 // this case should be rare, so it shouldn't be that big a deal.
1565 int wpos = mWindows.indexOf(win);
1566 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001567 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001568 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001570 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 reAddWindowLocked(wpos, win);
1572 }
1573 }
Romain Guy06882f82009-06-10 13:36:04 -07001574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 void logWindowList(String prefix) {
1576 int N = mWindows.size();
1577 while (N > 0) {
1578 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001579 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 }
1581 }
Romain Guy06882f82009-06-10 13:36:04 -07001582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 void moveInputMethodDialogsLocked(int pos) {
1584 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001587 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 for (int i=0; i<N; i++) {
1589 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1590 }
1591 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001592 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 logWindowList(" ");
1594 }
Romain Guy06882f82009-06-10 13:36:04 -07001595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 if (pos >= 0) {
1597 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1598 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001599 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 if (wp == mInputMethodWindow) {
1601 pos++;
1602 }
1603 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001604 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 for (int i=0; i<N; i++) {
1606 WindowState win = dialogs.get(i);
1607 win.mTargetAppToken = targetAppToken;
1608 pos = reAddWindowLocked(pos, win);
1609 }
1610 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001611 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 logWindowList(" ");
1613 }
1614 return;
1615 }
1616 for (int i=0; i<N; i++) {
1617 WindowState win = dialogs.get(i);
1618 win.mTargetAppToken = null;
1619 reAddWindowToListInOrderLocked(win);
1620 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001621 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 logWindowList(" ");
1623 }
1624 }
1625 }
Romain Guy06882f82009-06-10 13:36:04 -07001626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1628 final WindowState imWin = mInputMethodWindow;
1629 final int DN = mInputMethodDialogs.size();
1630 if (imWin == null && DN == 0) {
1631 return false;
1632 }
Romain Guy06882f82009-06-10 13:36:04 -07001633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1635 if (imPos >= 0) {
1636 // In this case, the input method windows are to be placed
1637 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 // First check to see if the input method windows are already
1640 // located here, and contiguous.
1641 final int N = mWindows.size();
1642 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001643 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 // Figure out the actual input method window that should be
1646 // at the bottom of their stack.
1647 WindowState baseImWin = imWin != null
1648 ? imWin : mInputMethodDialogs.get(0);
1649 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001650 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 if (cw.mSubLayer < 0) baseImWin = cw;
1652 }
Romain Guy06882f82009-06-10 13:36:04 -07001653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 if (firstImWin == baseImWin) {
1655 // The windows haven't moved... but are they still contiguous?
1656 // First find the top IM window.
1657 int pos = imPos+1;
1658 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001659 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 break;
1661 }
1662 pos++;
1663 }
1664 pos++;
1665 // Now there should be no more input method windows above.
1666 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001667 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 break;
1669 }
1670 pos++;
1671 }
1672 if (pos >= N) {
1673 // All is good!
1674 return false;
1675 }
1676 }
Romain Guy06882f82009-06-10 13:36:04 -07001677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 if (imWin != null) {
1679 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001680 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001681 logWindowList(" ");
1682 }
1683 imPos = tmpRemoveWindowLocked(imPos, imWin);
1684 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001685 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 logWindowList(" ");
1687 }
1688 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1689 reAddWindowLocked(imPos, imWin);
1690 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001691 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692 logWindowList(" ");
1693 }
1694 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1695 } else {
1696 moveInputMethodDialogsLocked(imPos);
1697 }
Romain Guy06882f82009-06-10 13:36:04 -07001698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 } else {
1700 // In this case, the input method windows go in a fixed layer,
1701 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001704 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705 tmpRemoveWindowLocked(0, imWin);
1706 imWin.mTargetAppToken = null;
1707 reAddWindowToListInOrderLocked(imWin);
1708 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001709 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 logWindowList(" ");
1711 }
1712 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1713 } else {
1714 moveInputMethodDialogsLocked(-1);;
1715 }
Romain Guy06882f82009-06-10 13:36:04 -07001716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 }
Romain Guy06882f82009-06-10 13:36:04 -07001718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 if (needAssignLayers) {
1720 assignLayersLocked();
1721 }
Romain Guy06882f82009-06-10 13:36:04 -07001722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 return true;
1724 }
Romain Guy06882f82009-06-10 13:36:04 -07001725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 void adjustInputMethodDialogsLocked() {
1727 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1728 }
Romain Guy06882f82009-06-10 13:36:04 -07001729
Dianne Hackborn25994b42009-09-04 14:21:19 -07001730 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001731 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001732 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1733 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1734 ? wallpaperTarget.mAppToken.animation : null)
1735 + " upper=" + mUpperWallpaperTarget
1736 + " lower=" + mLowerWallpaperTarget);
1737 return (wallpaperTarget != null
1738 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1739 && wallpaperTarget.mAppToken.animation != null)))
1740 || mUpperWallpaperTarget != null
1741 || mLowerWallpaperTarget != null;
1742 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001743
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001744 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1745 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001746
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001747 int adjustWallpaperWindowsLocked() {
1748 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001749
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001750 final int dw = mDisplay.getWidth();
1751 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001752
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001753 // First find top-most window that has asked to be on top of the
1754 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001755 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001756 int N = localmWindows.size();
1757 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001758 WindowState foundW = null;
1759 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001760 WindowState topCurW = null;
1761 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001762 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001763 int i = N;
1764 while (i > 0) {
1765 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001766 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001767 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1768 if (topCurW == null) {
1769 topCurW = w;
1770 topCurI = i;
1771 }
1772 continue;
1773 }
1774 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001775 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001776 // If this window's app token is hidden and not animating,
1777 // it is of no interest to us.
1778 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001779 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001780 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001781 continue;
1782 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001783 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001784 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001785 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1786 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001787 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001788 && (mWallpaperTarget == w
1789 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001790 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001791 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001792 foundW = w;
1793 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001794 if (w == mWallpaperTarget && ((w.mAppToken != null
1795 && w.mAppToken.animation != null)
1796 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001797 // The current wallpaper target is animating, so we'll
1798 // look behind it for another possible target and figure
1799 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001800 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001801 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001802 continue;
1803 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001804 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001805 } else if (w == mWindowDetachedWallpaper) {
1806 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001807 }
1808 }
1809
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001810 if (foundW == null && windowDetachedI >= 0) {
1811 if (DEBUG_WALLPAPER) Slog.v(TAG,
1812 "Found animating detached wallpaper activity: #" + i + "=" + w);
1813 foundW = w;
1814 foundI = windowDetachedI;
1815 }
1816
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001817 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001818 // If we are currently waiting for an app transition, and either
1819 // the current target or the next target are involved with it,
1820 // then hold off on doing anything with the wallpaper.
1821 // Note that we are checking here for just whether the target
1822 // is part of an app token... which is potentially overly aggressive
1823 // (the app token may not be involved in the transition), but good
1824 // enough (we'll just wait until whatever transition is pending
1825 // executes).
1826 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001827 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001828 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001829 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001830 }
1831 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001832 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001833 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001834 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001835 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001836 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001837
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001838 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001839 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001840 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001841 + " oldTarget: " + mWallpaperTarget);
1842 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001843
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001844 mLowerWallpaperTarget = null;
1845 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001846
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001847 WindowState oldW = mWallpaperTarget;
1848 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001849
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001850 // Now what is happening... if the current and new targets are
1851 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001852 if (foundW != null && oldW != null) {
1853 boolean oldAnim = oldW.mAnimation != null
1854 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1855 boolean foundAnim = foundW.mAnimation != null
1856 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001857 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001858 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001859 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001860 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001861 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001862 int oldI = localmWindows.indexOf(oldW);
1863 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001865 }
1866 if (oldI >= 0) {
1867 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001868 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001869 + "=" + oldW + "; new#" + foundI
1870 + "=" + foundW);
1871 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001872
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001873 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001874 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001875 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001876 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001877 }
1878 mWallpaperTarget = oldW;
1879 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001880
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001881 // Now set the upper and lower wallpaper targets
1882 // correctly, and make sure that we are positioning
1883 // the wallpaper below the lower.
1884 if (foundI > oldI) {
1885 // The new target is on top of the old one.
1886 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001887 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001888 }
1889 mUpperWallpaperTarget = foundW;
1890 mLowerWallpaperTarget = oldW;
1891 foundW = oldW;
1892 foundI = oldI;
1893 } else {
1894 // The new target is below the old one.
1895 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001896 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001897 }
1898 mUpperWallpaperTarget = oldW;
1899 mLowerWallpaperTarget = foundW;
1900 }
1901 }
1902 }
1903 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001904
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001905 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001906 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001907 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1908 || (mLowerWallpaperTarget.mAppToken != null
1909 && mLowerWallpaperTarget.mAppToken.animation != null);
1910 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1911 || (mUpperWallpaperTarget.mAppToken != null
1912 && mUpperWallpaperTarget.mAppToken.animation != null);
1913 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001914 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001915 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001916 }
1917 mLowerWallpaperTarget = null;
1918 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001919 }
1920 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001921
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001922 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001923 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001924 // The window is visible to the compositor... but is it visible
1925 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001926 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001927 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001928
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001929 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001930 // its layer adjustment. Only do this if we are not transfering
1931 // between two wallpaper targets.
1932 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001933 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001934 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001935
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001936 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1937 * TYPE_LAYER_MULTIPLIER
1938 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001939
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001940 // Now w is the window we are supposed to be behind... but we
1941 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001942 // AND any starting window associated with it, AND below the
1943 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001944 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001945 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001946 if (wb.mBaseLayer < maxLayer &&
1947 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001948 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001949 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001950 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001951 // This window is not related to the previous one in any
1952 // interesting way, so stop here.
1953 break;
1954 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001955 foundW = wb;
1956 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001957 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001958 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001959 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001960 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001961
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001962 if (foundW == null && topCurW != null) {
1963 // There is no wallpaper target, so it goes at the bottom.
1964 // We will assume it is the same place as last time, if known.
1965 foundW = topCurW;
1966 foundI = topCurI+1;
1967 } else {
1968 // Okay i is the position immediately above the wallpaper. Look at
1969 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001970 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001971 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001972
Dianne Hackborn284ac932009-08-28 10:34:25 -07001973 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001974 if (mWallpaperTarget.mWallpaperX >= 0) {
1975 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001976 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001977 }
1978 if (mWallpaperTarget.mWallpaperY >= 0) {
1979 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001980 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001981 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001982 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001983
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001984 // Start stepping backwards from here, ensuring that our wallpaper windows
1985 // are correctly placed.
1986 int curTokenIndex = mWallpaperTokens.size();
1987 while (curTokenIndex > 0) {
1988 curTokenIndex--;
1989 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001990 if (token.hidden == visible) {
1991 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1992 token.hidden = !visible;
1993 // Need to do a layout to ensure the wallpaper now has the
1994 // correct size.
1995 mLayoutNeeded = true;
1996 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001997
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001998 int curWallpaperIndex = token.windows.size();
1999 while (curWallpaperIndex > 0) {
2000 curWallpaperIndex--;
2001 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002002
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002003 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002004 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002005 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002006
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002007 // First, make sure the client has the current visibility
2008 // state.
2009 if (wallpaper.mWallpaperVisible != visible) {
2010 wallpaper.mWallpaperVisible = visible;
2011 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002013 "Setting visibility of wallpaper " + wallpaper
2014 + ": " + visible);
2015 wallpaper.mClient.dispatchAppVisibility(visible);
2016 } catch (RemoteException e) {
2017 }
2018 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002019
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002020 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002021 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002022 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002023
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002024 // First, if this window is at the current index, then all
2025 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002026 if (wallpaper == foundW) {
2027 foundI--;
2028 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07002029 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002030 continue;
2031 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002033 // The window didn't match... the current wallpaper window,
2034 // wherever it is, is in the wrong place, so make sure it is
2035 // not in the list.
2036 int oldIndex = localmWindows.indexOf(wallpaper);
2037 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002038 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002039 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002040 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002041 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002042 if (oldIndex < foundI) {
2043 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002044 }
2045 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002046
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002047 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002048 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
2049 Slog.v(TAG, "Moving wallpaper " + wallpaper
2050 + " from " + oldIndex + " to " + foundI);
2051 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002052
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002053 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002054 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002055 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002056 }
2057 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002058
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002059 return changed;
2060 }
2061
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002062 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002063 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002064 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002065 mWallpaperAnimLayerAdjustment = adj;
2066 int curTokenIndex = mWallpaperTokens.size();
2067 while (curTokenIndex > 0) {
2068 curTokenIndex--;
2069 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2070 int curWallpaperIndex = token.windows.size();
2071 while (curWallpaperIndex > 0) {
2072 curWallpaperIndex--;
2073 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2074 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002075 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002076 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002077 }
2078 }
2079 }
2080
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002081 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2082 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002083 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002084 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002085 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002086 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002087 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2088 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2089 changed = wallpaperWin.mXOffset != offset;
2090 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002091 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002092 + wallpaperWin + " x: " + offset);
2093 wallpaperWin.mXOffset = offset;
2094 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002095 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002096 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002097 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002098 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002099 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002100
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002101 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002102 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002103 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2104 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2105 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002106 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002107 + wallpaperWin + " y: " + offset);
2108 changed = true;
2109 wallpaperWin.mYOffset = offset;
2110 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002111 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002112 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002113 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002114 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002115 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002116
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002117 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002118 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002119 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002120 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2121 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002122 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002123 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002124 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002125 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002126 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2127 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002128 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002129 if (mWaitingOnWallpaper != null) {
2130 long start = SystemClock.uptimeMillis();
2131 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2132 < start) {
2133 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002135 "Waiting for offset complete...");
2136 mWindowMap.wait(WALLPAPER_TIMEOUT);
2137 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002138 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002139 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002140 if ((start+WALLPAPER_TIMEOUT)
2141 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002142 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002143 + wallpaperWin);
2144 mLastWallpaperTimeoutTime = start;
2145 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002146 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002147 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002148 }
2149 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002150 } catch (RemoteException e) {
2151 }
2152 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002153
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002154 return changed;
2155 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002156
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002157 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002158 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002159 if (mWaitingOnWallpaper != null &&
2160 mWaitingOnWallpaper.mClient.asBinder() == window) {
2161 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002162 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002163 }
2164 }
2165 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002166
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002167 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002168 final int dw = mDisplay.getWidth();
2169 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002170
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002171 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002172
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002173 WindowState target = mWallpaperTarget;
2174 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002175 if (target.mWallpaperX >= 0) {
2176 mLastWallpaperX = target.mWallpaperX;
2177 } else if (changingTarget.mWallpaperX >= 0) {
2178 mLastWallpaperX = changingTarget.mWallpaperX;
2179 }
2180 if (target.mWallpaperY >= 0) {
2181 mLastWallpaperY = target.mWallpaperY;
2182 } else if (changingTarget.mWallpaperY >= 0) {
2183 mLastWallpaperY = changingTarget.mWallpaperY;
2184 }
2185 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002186
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002187 int curTokenIndex = mWallpaperTokens.size();
2188 while (curTokenIndex > 0) {
2189 curTokenIndex--;
2190 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2191 int curWallpaperIndex = token.windows.size();
2192 while (curWallpaperIndex > 0) {
2193 curWallpaperIndex--;
2194 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2195 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2196 wallpaper.computeShownFrameLocked();
2197 changed = true;
2198 // We only want to be synchronous with one wallpaper.
2199 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002200 }
2201 }
2202 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002203
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002204 return changed;
2205 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002206
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002207 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002208 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002209 final int dw = mDisplay.getWidth();
2210 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002211
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002212 int curTokenIndex = mWallpaperTokens.size();
2213 while (curTokenIndex > 0) {
2214 curTokenIndex--;
2215 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002216 if (token.hidden == visible) {
2217 token.hidden = !visible;
2218 // Need to do a layout to ensure the wallpaper now has the
2219 // correct size.
2220 mLayoutNeeded = true;
2221 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002222
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002223 int curWallpaperIndex = token.windows.size();
2224 while (curWallpaperIndex > 0) {
2225 curWallpaperIndex--;
2226 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2227 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002228 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002229 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002230
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002231 if (wallpaper.mWallpaperVisible != visible) {
2232 wallpaper.mWallpaperVisible = visible;
2233 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002234 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002235 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002236 + ": " + visible);
2237 wallpaper.mClient.dispatchAppVisibility(visible);
2238 } catch (RemoteException e) {
2239 }
2240 }
2241 }
2242 }
2243 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 public int addWindow(Session session, IWindow client,
2246 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002247 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248 int res = mPolicy.checkAddPermission(attrs);
2249 if (res != WindowManagerImpl.ADD_OKAY) {
2250 return res;
2251 }
Romain Guy06882f82009-06-10 13:36:04 -07002252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 boolean reportNewConfig = false;
2254 WindowState attachedWindow = null;
2255 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002256 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002260 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 }
Romain Guy06882f82009-06-10 13:36:04 -07002262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002264 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2266 }
2267
2268 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002269 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002271 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 + attrs.token + ". Aborting.");
2273 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2274 }
2275 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2276 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002277 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 + attrs.token + ". Aborting.");
2279 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2280 }
2281 }
2282
2283 boolean addToken = false;
2284 WindowToken token = mTokenMap.get(attrs.token);
2285 if (token == null) {
2286 if (attrs.type >= FIRST_APPLICATION_WINDOW
2287 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002288 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 + attrs.token + ". Aborting.");
2290 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2291 }
2292 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002293 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 + attrs.token + ". Aborting.");
2295 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2296 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002297 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002298 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002299 + attrs.token + ". Aborting.");
2300 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 token = new WindowToken(attrs.token, -1, false);
2303 addToken = true;
2304 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2305 && attrs.type <= LAST_APPLICATION_WINDOW) {
2306 AppWindowToken atoken = token.appWindowToken;
2307 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002308 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 + token + ". Aborting.");
2310 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2311 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002312 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 + token + ". Aborting.");
2314 return WindowManagerImpl.ADD_APP_EXITING;
2315 }
2316 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2317 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002318 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2320 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2321 }
2322 } else if (attrs.type == TYPE_INPUT_METHOD) {
2323 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002324 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 + attrs.token + ". Aborting.");
2326 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2327 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002328 } else if (attrs.type == TYPE_WALLPAPER) {
2329 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002330 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002331 + attrs.token + ". Aborting.");
2332 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 }
2335
2336 win = new WindowState(session, client, token,
2337 attachedWindow, attrs, viewVisibility);
2338 if (win.mDeathRecipient == null) {
2339 // Client has apparently died, so there is no reason to
2340 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002341 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 + " that is dead, aborting.");
2343 return WindowManagerImpl.ADD_APP_EXITING;
2344 }
2345
2346 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 res = mPolicy.prepareAddWindowLw(win, attrs);
2349 if (res != WindowManagerImpl.ADD_OKAY) {
2350 return res;
2351 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002352
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002353 if (outInputChannel != null) {
2354 String name = win.makeInputChannelName();
2355 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2356 win.mInputChannel = inputChannels[0];
2357 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2358
Jeff Brown928e0542011-01-10 11:17:36 -08002359 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361
2362 // From now on, no exceptions or errors allowed!
2363
2364 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002365
Dianne Hackborn5132b372010-07-29 12:51:35 -07002366 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (addToken) {
2369 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
2371 win.attach();
2372 mWindowMap.put(client.asBinder(), win);
2373
2374 if (attrs.type == TYPE_APPLICATION_STARTING &&
2375 token.appWindowToken != null) {
2376 token.appWindowToken.startingWindow = win;
2377 }
2378
2379 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 if (attrs.type == TYPE_INPUT_METHOD) {
2382 mInputMethodWindow = win;
2383 addInputMethodWindowToListLocked(win);
2384 imMayMove = false;
2385 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2386 mInputMethodDialogs.add(win);
2387 addWindowToListInOrderLocked(win, true);
2388 adjustInputMethodDialogsLocked();
2389 imMayMove = false;
2390 } else {
2391 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002392 if (attrs.type == TYPE_WALLPAPER) {
2393 mLastWallpaperTimeoutTime = 0;
2394 adjustWallpaperWindowsLocked();
2395 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002396 adjustWallpaperWindowsLocked();
2397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 }
Romain Guy06882f82009-06-10 13:36:04 -07002399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 if (mInTouchMode) {
2405 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2406 }
2407 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2408 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2409 }
Romain Guy06882f82009-06-10 13:36:04 -07002410
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002411 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002413 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2414 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 imMayMove = false;
2416 }
2417 }
Romain Guy06882f82009-06-10 13:36:04 -07002418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002420 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 }
Romain Guy06882f82009-06-10 13:36:04 -07002422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 assignLayersLocked();
2424 // Don't do layout here, the window must call
2425 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 //dump();
2428
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002429 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002430 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002431 }
Jeff Brown349703e2010-06-22 01:27:15 -07002432
Joe Onorato8a9b2202010-02-26 18:56:32 -08002433 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 TAG, "New client " + client.asBinder()
2435 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002436
2437 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2438 reportNewConfig = true;
2439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 }
2441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 if (reportNewConfig) {
2443 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 return res;
2449 }
Romain Guy06882f82009-06-10 13:36:04 -07002450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 public void removeWindow(Session session, IWindow client) {
2452 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002453 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 if (win == null) {
2455 return;
2456 }
2457 removeWindowLocked(session, win);
2458 }
2459 }
Romain Guy06882f82009-06-10 13:36:04 -07002460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 public void removeWindowLocked(Session session, WindowState win) {
2462
Joe Onorato8a9b2202010-02-26 18:56:32 -08002463 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 TAG, "Remove " + win + " client="
2465 + Integer.toHexString(System.identityHashCode(
2466 win.mClient.asBinder()))
2467 + ", surface=" + win.mSurface);
2468
2469 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002470
2471 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002472
Joe Onorato8a9b2202010-02-26 18:56:32 -08002473 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2475 + " mExiting=" + win.mExiting
2476 + " isAnimating=" + win.isAnimating()
2477 + " app-animation="
2478 + (win.mAppToken != null ? win.mAppToken.animation : null)
2479 + " inPendingTransaction="
2480 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2481 + " mDisplayFrozen=" + mDisplayFrozen);
2482 // Visibility of the removed window. Will be used later to update orientation later on.
2483 boolean wasVisible = false;
2484 // First, see if we need to run an animation. If we do, we have
2485 // to hold off on removing the window until the animation is done.
2486 // If the display is frozen, just remove immediately, since the
2487 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002488 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 // If we are not currently running the exit animation, we
2490 // need to see about starting one.
2491 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2494 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2495 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2496 }
2497 // Try starting an animation.
2498 if (applyAnimationLocked(win, transit, false)) {
2499 win.mExiting = true;
2500 }
2501 }
2502 if (win.mExiting || win.isAnimating()) {
2503 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002504 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002505 win.mExiting = true;
2506 win.mRemoveOnExit = true;
2507 mLayoutNeeded = true;
2508 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2509 performLayoutAndPlaceSurfacesLocked();
2510 if (win.mAppToken != null) {
2511 win.mAppToken.updateReportedVisibilityLocked();
2512 }
2513 //dump();
2514 Binder.restoreCallingIdentity(origId);
2515 return;
2516 }
2517 }
2518
2519 removeWindowInnerLocked(session, win);
2520 // Removing a visible window will effect the computed orientation
2521 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002522 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002523 != mForcedAppOrientation
2524 && updateOrientationFromAppTokensLocked()) {
2525 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 }
2527 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2528 Binder.restoreCallingIdentity(origId);
2529 }
Romain Guy06882f82009-06-10 13:36:04 -07002530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002532 if (win.mRemoved) {
2533 // Nothing to do.
2534 return;
2535 }
2536
2537 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2538 WindowState cwin = win.mChildWindows.get(i);
2539 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2540 + win);
2541 removeWindowInnerLocked(cwin.mSession, cwin);
2542 }
2543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 if (mInputMethodTarget == win) {
2547 moveInputMethodWindowsIfNeededLocked(false);
2548 }
Romain Guy06882f82009-06-10 13:36:04 -07002549
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002550 if (false) {
2551 RuntimeException e = new RuntimeException("here");
2552 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002553 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002554 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 mPolicy.removeWindowLw(win);
2557 win.removeLocked();
2558
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002559 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 mWindowMap.remove(win.mClient.asBinder());
2561 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002562 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002563 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002564 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002565
2566 if (mInputMethodWindow == win) {
2567 mInputMethodWindow = null;
2568 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2569 mInputMethodDialogs.remove(win);
2570 }
Romain Guy06882f82009-06-10 13:36:04 -07002571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 final WindowToken token = win.mToken;
2573 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002574 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 token.windows.remove(win);
2576 if (atoken != null) {
2577 atoken.allAppWindows.remove(win);
2578 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002579 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002580 TAG, "**** Removing window " + win + ": count="
2581 + token.windows.size());
2582 if (token.windows.size() == 0) {
2583 if (!token.explicit) {
2584 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 } else if (atoken != null) {
2586 atoken.firstWindowDrawn = false;
2587 }
2588 }
2589
2590 if (atoken != null) {
2591 if (atoken.startingWindow == win) {
2592 atoken.startingWindow = null;
2593 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2594 // If this is the last window and we had requested a starting
2595 // transition window, well there is no point now.
2596 atoken.startingData = null;
2597 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2598 // If this is the last window except for a starting transition
2599 // window, we need to get rid of the starting transition.
2600 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 + ": no more real windows");
2603 }
2604 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2605 mH.sendMessage(m);
2606 }
2607 }
Romain Guy06882f82009-06-10 13:36:04 -07002608
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002609 if (win.mAttrs.type == TYPE_WALLPAPER) {
2610 mLastWallpaperTimeoutTime = 0;
2611 adjustWallpaperWindowsLocked();
2612 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002613 adjustWallpaperWindowsLocked();
2614 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 if (!mInLayout) {
2617 assignLayersLocked();
2618 mLayoutNeeded = true;
2619 performLayoutAndPlaceSurfacesLocked();
2620 if (win.mAppToken != null) {
2621 win.mAppToken.updateReportedVisibilityLocked();
2622 }
2623 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002624
2625 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626 }
2627
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002628 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2629 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2630 + ": " + msg + " / " + w.mAttrs.getTitle();
2631 if (where != null) {
2632 Slog.i(TAG, str, where);
2633 } else {
2634 Slog.i(TAG, str);
2635 }
2636 }
2637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2639 long origId = Binder.clearCallingIdentity();
2640 try {
2641 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002642 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002644 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 Surface.openTransaction();
2646 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002647 if (SHOW_TRANSACTIONS) logSurface(w,
2648 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 w.mSurface.setTransparentRegionHint(region);
2650 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002651 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 Surface.closeTransaction();
2653 }
2654 }
2655 }
2656 } finally {
2657 Binder.restoreCallingIdentity(origId);
2658 }
2659 }
2660
2661 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002662 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 Rect visibleInsets) {
2664 long origId = Binder.clearCallingIdentity();
2665 try {
2666 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002667 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 if (w != null) {
2669 w.mGivenInsetsPending = false;
2670 w.mGivenContentInsets.set(contentInsets);
2671 w.mGivenVisibleInsets.set(visibleInsets);
2672 w.mTouchableInsets = touchableInsets;
2673 mLayoutNeeded = true;
2674 performLayoutAndPlaceSurfacesLocked();
2675 }
2676 }
2677 } finally {
2678 Binder.restoreCallingIdentity(origId);
2679 }
2680 }
Romain Guy06882f82009-06-10 13:36:04 -07002681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 public void getWindowDisplayFrame(Session session, IWindow client,
2683 Rect outDisplayFrame) {
2684 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002685 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 if (win == null) {
2687 outDisplayFrame.setEmpty();
2688 return;
2689 }
2690 outDisplayFrame.set(win.mDisplayFrame);
2691 }
2692 }
2693
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002694 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2695 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002696 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2697 window.mWallpaperX = x;
2698 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002699 window.mWallpaperXStep = xStep;
2700 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002701 if (updateWallpaperOffsetLocked(window, true)) {
2702 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002703 }
2704 }
2705 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002706
Dianne Hackborn75804932009-10-20 20:15:20 -07002707 void wallpaperCommandComplete(IBinder window, Bundle result) {
2708 synchronized (mWindowMap) {
2709 if (mWaitingOnWallpaper != null &&
2710 mWaitingOnWallpaper.mClient.asBinder() == window) {
2711 mWaitingOnWallpaper = null;
2712 mWindowMap.notifyAll();
2713 }
2714 }
2715 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002716
Dianne Hackborn75804932009-10-20 20:15:20 -07002717 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2718 String action, int x, int y, int z, Bundle extras, boolean sync) {
2719 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2720 || window == mUpperWallpaperTarget) {
2721 boolean doWait = sync;
2722 int curTokenIndex = mWallpaperTokens.size();
2723 while (curTokenIndex > 0) {
2724 curTokenIndex--;
2725 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2726 int curWallpaperIndex = token.windows.size();
2727 while (curWallpaperIndex > 0) {
2728 curWallpaperIndex--;
2729 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2730 try {
2731 wallpaper.mClient.dispatchWallpaperCommand(action,
2732 x, y, z, extras, sync);
2733 // We only want to be synchronous with one wallpaper.
2734 sync = false;
2735 } catch (RemoteException e) {
2736 }
2737 }
2738 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002739
Dianne Hackborn75804932009-10-20 20:15:20 -07002740 if (doWait) {
2741 // XXX Need to wait for result.
2742 }
2743 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002744
Dianne Hackborn75804932009-10-20 20:15:20 -07002745 return null;
2746 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 public int relayoutWindow(Session session, IWindow client,
2749 WindowManager.LayoutParams attrs, int requestedWidth,
2750 int requestedHeight, int viewVisibility, boolean insetsPending,
2751 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002752 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002753 boolean displayed = false;
2754 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002755 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002759 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760 if (win == null) {
2761 return 0;
2762 }
2763 win.mRequestedWidth = requestedWidth;
2764 win.mRequestedHeight = requestedHeight;
2765
2766 if (attrs != null) {
2767 mPolicy.adjustWindowParamsLw(attrs);
2768 }
Romain Guy06882f82009-06-10 13:36:04 -07002769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 int attrChanges = 0;
2771 int flagChanges = 0;
2772 if (attrs != null) {
2773 flagChanges = win.mAttrs.flags ^= attrs.flags;
2774 attrChanges = win.mAttrs.copyFrom(attrs);
2775 }
2776
Joe Onorato8a9b2202010-02-26 18:56:32 -08002777 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778
2779 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2780 win.mAlpha = attrs.alpha;
2781 }
2782
2783 final boolean scaledWindow =
2784 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2785
2786 if (scaledWindow) {
2787 // requested{Width|Height} Surface's physical size
2788 // attrs.{width|height} Size on screen
2789 win.mHScale = (attrs.width != requestedWidth) ?
2790 (attrs.width / (float)requestedWidth) : 1.0f;
2791 win.mVScale = (attrs.height != requestedHeight) ?
2792 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002793 } else {
2794 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 }
2796
2797 boolean imMayMove = (flagChanges&(
2798 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2799 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002801 boolean focusMayChange = win.mViewVisibility != viewVisibility
2802 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2803 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002804
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002805 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2806 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 win.mRelayoutCalled = true;
2809 final int oldVisibility = win.mViewVisibility;
2810 win.mViewVisibility = viewVisibility;
2811 if (viewVisibility == View.VISIBLE &&
2812 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2813 displayed = !win.isVisibleLw();
2814 if (win.mExiting) {
2815 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002816 if (win.mAnimation != null) {
2817 win.mAnimation.cancel();
2818 win.mAnimation = null;
2819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002820 }
2821 if (win.mDestroying) {
2822 win.mDestroying = false;
2823 mDestroySurface.remove(win);
2824 }
2825 if (oldVisibility == View.GONE) {
2826 win.mEnterAnimationPending = true;
2827 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002828 if (displayed) {
2829 if (win.mSurface != null && !win.mDrawPending
2830 && !win.mCommitDrawPending && !mDisplayFrozen
2831 && mPolicy.isScreenOn()) {
2832 applyEnterAnimationLocked(win);
2833 }
2834 if ((win.mAttrs.flags
2835 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2836 if (DEBUG_VISIBILITY) Slog.v(TAG,
2837 "Relayout window turning screen on: " + win);
2838 win.mTurnOnScreen = true;
2839 }
2840 int diff = 0;
2841 if (win.mConfiguration != mCurConfiguration
2842 && (win.mConfiguration == null
2843 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2844 win.mConfiguration = mCurConfiguration;
2845 if (DEBUG_CONFIGURATION) {
2846 Slog.i(TAG, "Window " + win + " visible with new config: "
2847 + win.mConfiguration + " / 0x"
2848 + Integer.toHexString(diff));
2849 }
2850 outConfig.setTo(mCurConfiguration);
2851 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2854 // To change the format, we need to re-build the surface.
2855 win.destroySurfaceLocked();
2856 displayed = true;
2857 }
2858 try {
2859 Surface surface = win.createSurfaceLocked();
2860 if (surface != null) {
2861 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002862 win.mReportDestroySurface = false;
2863 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002864 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002865 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002867 // For some reason there isn't a surface. Clear the
2868 // caller's object so they see the same state.
2869 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 }
2871 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002872 mInputMonitor.updateInputWindowsLw();
2873
Joe Onorato8a9b2202010-02-26 18:56:32 -08002874 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002875 + client + " (" + win.mAttrs.getTitle() + ")",
2876 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002877 Binder.restoreCallingIdentity(origId);
2878 return 0;
2879 }
2880 if (displayed) {
2881 focusMayChange = true;
2882 }
2883 if (win.mAttrs.type == TYPE_INPUT_METHOD
2884 && mInputMethodWindow == null) {
2885 mInputMethodWindow = win;
2886 imMayMove = true;
2887 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002888 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2889 && win.mAppToken != null
2890 && win.mAppToken.startingWindow != null) {
2891 // Special handling of starting window over the base
2892 // window of the app: propagate lock screen flags to it,
2893 // to provide the correct semantics while starting.
2894 final int mask =
2895 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002896 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2897 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002898 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2899 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 } else {
2902 win.mEnterAnimationPending = false;
2903 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002904 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002905 + ": mExiting=" + win.mExiting
2906 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 // If we are not currently running the exit animation, we
2908 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002909 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 // Try starting an animation; if there isn't one, we
2911 // can destroy the surface right away.
2912 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2913 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2914 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2915 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002916 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002918 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002920 } else if (win.isAnimating()) {
2921 // Currently in a hide animation... turn this into
2922 // an exit.
2923 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002924 } else if (win == mWallpaperTarget) {
2925 // If the wallpaper is currently behind this
2926 // window, we need to change both of them inside
2927 // of a transaction to avoid artifacts.
2928 win.mExiting = true;
2929 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 } else {
2931 if (mInputMethodWindow == win) {
2932 mInputMethodWindow = null;
2933 }
2934 win.destroySurfaceLocked();
2935 }
2936 }
2937 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002938
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002939 if (win.mSurface == null || (win.getAttrs().flags
2940 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2941 || win.mSurfacePendingDestroy) {
2942 // We are being called from a local process, which
2943 // means outSurface holds its current surface. Ensure the
2944 // surface object is cleared, but we don't want it actually
2945 // destroyed at this point.
2946 win.mSurfacePendingDestroy = false;
2947 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002948 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002949 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002950 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002951 "Keeping surface, will report destroy: " + win);
2952 win.mReportDestroySurface = true;
2953 outSurface.copyFrom(win.mSurface);
2954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 if (focusMayChange) {
2958 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2959 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 imMayMove = false;
2961 }
2962 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2963 }
Romain Guy06882f82009-06-10 13:36:04 -07002964
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002965 // updateFocusedWindowLocked() already assigned layers so we only need to
2966 // reassign them at this point if the IM window state gets shuffled
2967 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002969 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002970 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2971 // Little hack here -- we -should- be able to rely on the
2972 // function to return true if the IME has moved and needs
2973 // its layer recomputed. However, if the IME was hidden
2974 // and isn't actually moved in the list, its layer may be
2975 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 assignLayers = true;
2977 }
2978 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002979 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002980 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002981 assignLayers = true;
2982 }
2983 }
Romain Guy06882f82009-06-10 13:36:04 -07002984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 mLayoutNeeded = true;
2986 win.mGivenInsetsPending = insetsPending;
2987 if (assignLayers) {
2988 assignLayersLocked();
2989 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002990 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002992 if (displayed && win.mIsWallpaper) {
2993 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002994 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996 if (win.mAppToken != null) {
2997 win.mAppToken.updateReportedVisibilityLocked();
2998 }
2999 outFrame.set(win.mFrame);
3000 outContentInsets.set(win.mContentInsets);
3001 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003002 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003003 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07003004 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 + ", requestedHeight=" + requestedHeight
3006 + ", viewVisibility=" + viewVisibility
3007 + "\nRelayout returning frame=" + outFrame
3008 + ", surface=" + outSurface);
3009
Joe Onorato8a9b2202010-02-26 18:56:32 -08003010 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3012
3013 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07003014
3015 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 }
3017
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003018 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 sendNewConfiguration();
3020 }
Romain Guy06882f82009-06-10 13:36:04 -07003021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
3025 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
3026 }
3027
3028 public void finishDrawingWindow(Session session, IWindow client) {
3029 final long origId = Binder.clearCallingIdentity();
3030 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003031 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003033 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3034 adjustWallpaperWindowsLocked();
3035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 mLayoutNeeded = true;
3037 performLayoutAndPlaceSurfacesLocked();
3038 }
3039 }
3040 Binder.restoreCallingIdentity(origId);
3041 }
3042
3043 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003044 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003045 + (lp != null ? lp.packageName : null)
3046 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3047 if (lp != null && lp.windowAnimations != 0) {
3048 // If this is a system resource, don't try to load it from the
3049 // application resources. It is nice to avoid loading application
3050 // resources if we can.
3051 String packageName = lp.packageName != null ? lp.packageName : "android";
3052 int resId = lp.windowAnimations;
3053 if ((resId&0xFF000000) == 0x01000000) {
3054 packageName = "android";
3055 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003056 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 + packageName);
3058 return AttributeCache.instance().get(packageName, resId,
3059 com.android.internal.R.styleable.WindowAnimation);
3060 }
3061 return null;
3062 }
Romain Guy06882f82009-06-10 13:36:04 -07003063
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003064 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003065 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003066 + packageName + " resId=0x" + Integer.toHexString(resId));
3067 if (packageName != null) {
3068 if ((resId&0xFF000000) == 0x01000000) {
3069 packageName = "android";
3070 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003071 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003072 + packageName);
3073 return AttributeCache.instance().get(packageName, resId,
3074 com.android.internal.R.styleable.WindowAnimation);
3075 }
3076 return null;
3077 }
3078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 private void applyEnterAnimationLocked(WindowState win) {
3080 int transit = WindowManagerPolicy.TRANSIT_SHOW;
3081 if (win.mEnterAnimationPending) {
3082 win.mEnterAnimationPending = false;
3083 transit = WindowManagerPolicy.TRANSIT_ENTER;
3084 }
3085
3086 applyAnimationLocked(win, transit, true);
3087 }
3088
3089 private boolean applyAnimationLocked(WindowState win,
3090 int transit, boolean isEntrance) {
3091 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3092 // If we are trying to apply an animation, but already running
3093 // an animation of the same type, then just leave that one alone.
3094 return true;
3095 }
Romain Guy06882f82009-06-10 13:36:04 -07003096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 // Only apply an animation if the display isn't frozen. If it is
3098 // frozen, there is no reason to animate and it can cause strange
3099 // artifacts when we unfreeze the display if some different animation
3100 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003101 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003102 int anim = mPolicy.selectAnimationLw(win, transit);
3103 int attr = -1;
3104 Animation a = null;
3105 if (anim != 0) {
3106 a = AnimationUtils.loadAnimation(mContext, anim);
3107 } else {
3108 switch (transit) {
3109 case WindowManagerPolicy.TRANSIT_ENTER:
3110 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3111 break;
3112 case WindowManagerPolicy.TRANSIT_EXIT:
3113 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3114 break;
3115 case WindowManagerPolicy.TRANSIT_SHOW:
3116 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3117 break;
3118 case WindowManagerPolicy.TRANSIT_HIDE:
3119 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3120 break;
3121 }
3122 if (attr >= 0) {
3123 a = loadAnimation(win.mAttrs, attr);
3124 }
3125 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003126 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3128 + " mAnimation=" + win.mAnimation
3129 + " isEntrance=" + isEntrance);
3130 if (a != null) {
3131 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003132 RuntimeException e = null;
3133 if (!HIDE_STACK_CRAWLS) {
3134 e = new RuntimeException();
3135 e.fillInStackTrace();
3136 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003137 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 }
3139 win.setAnimation(a);
3140 win.mAnimationIsEntrance = isEntrance;
3141 }
3142 } else {
3143 win.clearAnimation();
3144 }
3145
3146 return win.mAnimation != null;
3147 }
3148
3149 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3150 int anim = 0;
3151 Context context = mContext;
3152 if (animAttr >= 0) {
3153 AttributeCache.Entry ent = getCachedAnimations(lp);
3154 if (ent != null) {
3155 context = ent.context;
3156 anim = ent.array.getResourceId(animAttr, 0);
3157 }
3158 }
3159 if (anim != 0) {
3160 return AnimationUtils.loadAnimation(context, anim);
3161 }
3162 return null;
3163 }
Romain Guy06882f82009-06-10 13:36:04 -07003164
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003165 private Animation loadAnimation(String packageName, int resId) {
3166 int anim = 0;
3167 Context context = mContext;
3168 if (resId >= 0) {
3169 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3170 if (ent != null) {
3171 context = ent.context;
3172 anim = resId;
3173 }
3174 }
3175 if (anim != 0) {
3176 return AnimationUtils.loadAnimation(context, anim);
3177 }
3178 return null;
3179 }
3180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 private boolean applyAnimationLocked(AppWindowToken wtoken,
3182 WindowManager.LayoutParams lp, int transit, boolean enter) {
3183 // Only apply an animation if the display isn't frozen. If it is
3184 // frozen, there is no reason to animate and it can cause strange
3185 // artifacts when we unfreeze the display if some different animation
3186 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003187 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003188 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003189 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003190 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003191 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003192 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003193 } else if (mNextAppTransitionPackage != null) {
3194 a = loadAnimation(mNextAppTransitionPackage, enter ?
3195 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003196 } else {
3197 int animAttr = 0;
3198 switch (transit) {
3199 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3200 animAttr = enter
3201 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3202 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3203 break;
3204 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3205 animAttr = enter
3206 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3207 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3208 break;
3209 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3210 animAttr = enter
3211 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3212 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3213 break;
3214 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3215 animAttr = enter
3216 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3217 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3218 break;
3219 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3220 animAttr = enter
3221 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3222 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3223 break;
3224 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3225 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003226 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003227 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3228 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003229 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003230 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003231 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3232 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003233 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003234 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003235 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003236 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3237 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3238 break;
3239 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3240 animAttr = enter
3241 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3242 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3243 break;
3244 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3245 animAttr = enter
3246 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3247 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003248 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003249 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003250 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003251 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003252 + " anim=" + a
3253 + " animAttr=0x" + Integer.toHexString(animAttr)
3254 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 if (a != null) {
3257 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003258 RuntimeException e = null;
3259 if (!HIDE_STACK_CRAWLS) {
3260 e = new RuntimeException();
3261 e.fillInStackTrace();
3262 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003263 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 }
3265 wtoken.setAnimation(a);
3266 }
3267 } else {
3268 wtoken.clearAnimation();
3269 }
3270
3271 return wtoken.animation != null;
3272 }
3273
3274 // -------------------------------------------------------------
3275 // Application Window Tokens
3276 // -------------------------------------------------------------
3277
3278 public void validateAppTokens(List tokens) {
3279 int v = tokens.size()-1;
3280 int m = mAppTokens.size()-1;
3281 while (v >= 0 && m >= 0) {
3282 AppWindowToken wtoken = mAppTokens.get(m);
3283 if (wtoken.removed) {
3284 m--;
3285 continue;
3286 }
3287 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003288 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3290 }
3291 v--;
3292 m--;
3293 }
3294 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003295 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 v--;
3297 }
3298 while (m >= 0) {
3299 AppWindowToken wtoken = mAppTokens.get(m);
3300 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003301 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 }
3303 m--;
3304 }
3305 }
3306
3307 boolean checkCallingPermission(String permission, String func) {
3308 // Quick check: if the calling permission is me, it's all okay.
3309 if (Binder.getCallingPid() == Process.myPid()) {
3310 return true;
3311 }
Romain Guy06882f82009-06-10 13:36:04 -07003312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313 if (mContext.checkCallingPermission(permission)
3314 == PackageManager.PERMISSION_GRANTED) {
3315 return true;
3316 }
3317 String msg = "Permission Denial: " + func + " from pid="
3318 + Binder.getCallingPid()
3319 + ", uid=" + Binder.getCallingUid()
3320 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003321 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 return false;
3323 }
Romain Guy06882f82009-06-10 13:36:04 -07003324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 AppWindowToken findAppWindowToken(IBinder token) {
3326 WindowToken wtoken = mTokenMap.get(token);
3327 if (wtoken == null) {
3328 return null;
3329 }
3330 return wtoken.appWindowToken;
3331 }
Romain Guy06882f82009-06-10 13:36:04 -07003332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003333 public void addWindowToken(IBinder token, int type) {
3334 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3335 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003336 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 }
Romain Guy06882f82009-06-10 13:36:04 -07003338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 synchronized(mWindowMap) {
3340 WindowToken wtoken = mTokenMap.get(token);
3341 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003342 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 return;
3344 }
3345 wtoken = new WindowToken(token, type, true);
3346 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003347 if (type == TYPE_WALLPAPER) {
3348 mWallpaperTokens.add(wtoken);
3349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350 }
3351 }
Romain Guy06882f82009-06-10 13:36:04 -07003352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 public void removeWindowToken(IBinder token) {
3354 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3355 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003356 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 }
3358
3359 final long origId = Binder.clearCallingIdentity();
3360 synchronized(mWindowMap) {
3361 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 if (wtoken != null) {
3363 boolean delayed = false;
3364 if (!wtoken.hidden) {
3365 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003367 final int N = wtoken.windows.size();
3368 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003370 for (int i=0; i<N; i++) {
3371 WindowState win = wtoken.windows.get(i);
3372
3373 if (win.isAnimating()) {
3374 delayed = true;
3375 }
Romain Guy06882f82009-06-10 13:36:04 -07003376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 if (win.isVisibleNow()) {
3378 applyAnimationLocked(win,
3379 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 changed = true;
3381 }
3382 }
3383
3384 if (changed) {
3385 mLayoutNeeded = true;
3386 performLayoutAndPlaceSurfacesLocked();
3387 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3388 }
Romain Guy06882f82009-06-10 13:36:04 -07003389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 if (delayed) {
3391 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003392 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3393 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 }
3395 }
Romain Guy06882f82009-06-10 13:36:04 -07003396
Jeff Brownc5ed5912010-07-14 18:48:53 -07003397 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003399 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 }
3401 }
3402 Binder.restoreCallingIdentity(origId);
3403 }
3404
3405 public void addAppToken(int addPos, IApplicationToken token,
3406 int groupId, int requestedOrientation, boolean fullscreen) {
3407 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3408 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003409 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 }
Jeff Brown349703e2010-06-22 01:27:15 -07003411
3412 // Get the dispatching timeout here while we are not holding any locks so that it
3413 // can be cached by the AppWindowToken. The timeout value is used later by the
3414 // input dispatcher in code that does hold locks. If we did not cache the value
3415 // here we would run the chance of introducing a deadlock between the window manager
3416 // (which holds locks while updating the input dispatcher state) and the activity manager
3417 // (which holds locks while querying the application token).
3418 long inputDispatchingTimeoutNanos;
3419 try {
3420 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3421 } catch (RemoteException ex) {
3422 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3423 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3424 }
Romain Guy06882f82009-06-10 13:36:04 -07003425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 synchronized(mWindowMap) {
3427 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3428 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003429 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 return;
3431 }
3432 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003433 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 wtoken.groupId = groupId;
3435 wtoken.appFullscreen = fullscreen;
3436 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003437 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003438 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 // Application tokens start out hidden.
3442 wtoken.hidden = true;
3443 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 //dump();
3446 }
3447 }
Romain Guy06882f82009-06-10 13:36:04 -07003448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 public void setAppGroupId(IBinder token, int groupId) {
3450 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3451 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003452 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453 }
3454
3455 synchronized(mWindowMap) {
3456 AppWindowToken wtoken = findAppWindowToken(token);
3457 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003458 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 return;
3460 }
3461 wtoken.groupId = groupId;
3462 }
3463 }
Romain Guy06882f82009-06-10 13:36:04 -07003464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 public int getOrientationFromWindowsLocked() {
3466 int pos = mWindows.size() - 1;
3467 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003468 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 pos--;
3470 if (wtoken.mAppToken != null) {
3471 // We hit an application window. so the orientation will be determined by the
3472 // app window. No point in continuing further.
3473 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3474 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003475 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 continue;
3477 }
3478 int req = wtoken.mAttrs.screenOrientation;
3479 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3480 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3481 continue;
3482 } else {
3483 return req;
3484 }
3485 }
3486 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3487 }
Romain Guy06882f82009-06-10 13:36:04 -07003488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003490 int pos = mAppTokens.size() - 1;
3491 int curGroup = 0;
3492 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3493 boolean findingBehind = false;
3494 boolean haveGroup = false;
3495 boolean lastFullscreen = false;
3496 while (pos >= 0) {
3497 AppWindowToken wtoken = mAppTokens.get(pos);
3498 pos--;
3499 // if we're about to tear down this window and not seek for
3500 // the behind activity, don't use it for orientation
3501 if (!findingBehind
3502 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3503 continue;
3504 }
3505
3506 if (!haveGroup) {
3507 // We ignore any hidden applications on the top.
3508 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003509 continue;
3510 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003511 haveGroup = true;
3512 curGroup = wtoken.groupId;
3513 lastOrientation = wtoken.requestedOrientation;
3514 } else if (curGroup != wtoken.groupId) {
3515 // If we have hit a new application group, and the bottom
3516 // of the previous group didn't explicitly say to use
3517 // the orientation behind it, and the last app was
3518 // full screen, then we'll stick with the
3519 // user's orientation.
3520 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3521 && lastFullscreen) {
3522 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003525 int or = wtoken.requestedOrientation;
3526 // If this application is fullscreen, and didn't explicitly say
3527 // to use the orientation behind it, then just take whatever
3528 // orientation it has and ignores whatever is under it.
3529 lastFullscreen = wtoken.appFullscreen;
3530 if (lastFullscreen
3531 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3532 return or;
3533 }
3534 // If this application has requested an explicit orientation,
3535 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003536 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3537 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003538 return or;
3539 }
3540 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3541 }
3542 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 }
Romain Guy06882f82009-06-10 13:36:04 -07003544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003546 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003547 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3548 "updateOrientationFromAppTokens()")) {
3549 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3550 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003551
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003552 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003554
3555 synchronized(mWindowMap) {
3556 if (updateOrientationFromAppTokensLocked()) {
3557 if (freezeThisOneIfNeeded != null) {
3558 AppWindowToken wtoken = findAppWindowToken(
3559 freezeThisOneIfNeeded);
3560 if (wtoken != null) {
3561 startAppFreezingScreenLocked(wtoken,
3562 ActivityInfo.CONFIG_ORIENTATION);
3563 }
3564 }
3565 config = computeNewConfigurationLocked();
3566
3567 } else if (currentConfig != null) {
3568 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003569 // state mismatches the activity manager's, update it,
3570 // disregarding font scale, which should remain set to
3571 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003572 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003573 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003574 if (computeNewConfigurationLocked(mTempConfiguration)) {
3575 if (currentConfig.diff(mTempConfiguration) != 0) {
3576 mWaitingForConfig = true;
3577 mLayoutNeeded = true;
3578 startFreezingDisplayLocked();
3579 config = new Configuration(mTempConfiguration);
3580 }
3581 }
3582 }
3583 }
3584
Dianne Hackborncfaef692009-06-15 14:24:44 -07003585 Binder.restoreCallingIdentity(ident);
3586 return config;
3587 }
3588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003590 * Determine the new desired orientation of the display, returning
3591 * a non-null new Configuration if it has changed from the current
3592 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3593 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3594 * SCREEN. This will typically be done for you if you call
3595 * sendNewConfiguration().
3596 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597 * The orientation is computed from non-application windows first. If none of
3598 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003599 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3601 * android.os.IBinder)
3602 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003603 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003604 if (mDisplayFrozen) {
3605 // If the display is frozen, some activities may be in the middle
3606 // of restarting, and thus have removed their old window. If the
3607 // window has the flag to hide the lock screen, then the lock screen
3608 // can re-appear and inflict its own orientation on us. Keep the
3609 // orientation stable until this all settles down.
3610 return false;
3611 }
3612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 long ident = Binder.clearCallingIdentity();
3615 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003616 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003619 mForcedAppOrientation = req;
3620 //send a message to Policy indicating orientation change to take
3621 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003622 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003623 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3624 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3625 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 }
3627 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003628
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003629 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003630 } finally {
3631 Binder.restoreCallingIdentity(ident);
3632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 }
Romain Guy06882f82009-06-10 13:36:04 -07003634
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003635 int computeForcedAppOrientationLocked() {
3636 int req = getOrientationFromWindowsLocked();
3637 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3638 req = getOrientationFromAppTokensLocked();
3639 }
3640 return req;
3641 }
Romain Guy06882f82009-06-10 13:36:04 -07003642
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003643 public void setNewConfiguration(Configuration config) {
3644 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3645 "setNewConfiguration()")) {
3646 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3647 }
3648
3649 synchronized(mWindowMap) {
3650 mCurConfiguration = new Configuration(config);
3651 mWaitingForConfig = false;
3652 performLayoutAndPlaceSurfacesLocked();
3653 }
3654 }
3655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3657 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3658 "setAppOrientation()")) {
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 }
Romain Guy06882f82009-06-10 13:36:04 -07003661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 synchronized(mWindowMap) {
3663 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3664 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003665 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 return;
3667 }
Romain Guy06882f82009-06-10 13:36:04 -07003668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 wtoken.requestedOrientation = requestedOrientation;
3670 }
3671 }
Romain Guy06882f82009-06-10 13:36:04 -07003672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 public int getAppOrientation(IApplicationToken token) {
3674 synchronized(mWindowMap) {
3675 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3676 if (wtoken == null) {
3677 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3678 }
Romain Guy06882f82009-06-10 13:36:04 -07003679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 return wtoken.requestedOrientation;
3681 }
3682 }
Romain Guy06882f82009-06-10 13:36:04 -07003683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3685 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3686 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003687 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 }
3689
3690 synchronized(mWindowMap) {
3691 boolean changed = false;
3692 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003693 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 changed = mFocusedApp != null;
3695 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003696 if (changed) {
3697 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 } else {
3700 AppWindowToken newFocus = findAppWindowToken(token);
3701 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003702 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 return;
3704 }
3705 changed = mFocusedApp != newFocus;
3706 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003707 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003708 if (changed) {
3709 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 }
3712
3713 if (moveFocusNow && changed) {
3714 final long origId = Binder.clearCallingIdentity();
3715 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3716 Binder.restoreCallingIdentity(origId);
3717 }
3718 }
3719 }
3720
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003721 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3723 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003724 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 }
Romain Guy06882f82009-06-10 13:36:04 -07003726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003728 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 TAG, "Prepare app transition: transit=" + transit
3730 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003731 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003732 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3733 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003735 } else if (!alwaysKeepCurrent) {
3736 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3737 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3738 // Opening a new task always supersedes a close for the anim.
3739 mNextAppTransition = transit;
3740 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3741 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3742 // Opening a new activity always supersedes a close for the anim.
3743 mNextAppTransition = transit;
3744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 }
3746 mAppTransitionReady = false;
3747 mAppTransitionTimeout = false;
3748 mStartingIconInTransition = false;
3749 mSkipAppTransitionAnimation = false;
3750 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3751 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3752 5000);
3753 }
3754 }
3755 }
3756
3757 public int getPendingAppTransition() {
3758 return mNextAppTransition;
3759 }
Romain Guy06882f82009-06-10 13:36:04 -07003760
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003761 public void overridePendingAppTransition(String packageName,
3762 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003763 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003764 mNextAppTransitionPackage = packageName;
3765 mNextAppTransitionEnter = enterAnim;
3766 mNextAppTransitionExit = exitAnim;
3767 }
3768 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 public void executeAppTransition() {
3771 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3772 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003773 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 }
Romain Guy06882f82009-06-10 13:36:04 -07003775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003777 if (DEBUG_APP_TRANSITIONS) {
3778 RuntimeException e = new RuntimeException("here");
3779 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003780 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003781 + mNextAppTransition, e);
3782 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003783 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003784 mAppTransitionReady = true;
3785 final long origId = Binder.clearCallingIdentity();
3786 performLayoutAndPlaceSurfacesLocked();
3787 Binder.restoreCallingIdentity(origId);
3788 }
3789 }
3790 }
3791
3792 public void setAppStartingWindow(IBinder token, String pkg,
3793 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003794 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3796 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003797 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 }
3799
3800 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003801 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3803 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 AppWindowToken wtoken = findAppWindowToken(token);
3806 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003807 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 return;
3809 }
3810
3811 // If the display is frozen, we won't do anything until the
3812 // actual window is displayed so there is no reason to put in
3813 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003814 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 return;
3816 }
Romain Guy06882f82009-06-10 13:36:04 -07003817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 if (wtoken.startingData != null) {
3819 return;
3820 }
Romain Guy06882f82009-06-10 13:36:04 -07003821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 if (transferFrom != null) {
3823 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3824 if (ttoken != null) {
3825 WindowState startingWindow = ttoken.startingWindow;
3826 if (startingWindow != null) {
3827 if (mStartingIconInTransition) {
3828 // In this case, the starting icon has already
3829 // been displayed, so start letting windows get
3830 // shown immediately without any more transitions.
3831 mSkipAppTransitionAnimation = true;
3832 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003833 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 "Moving existing starting from " + ttoken
3835 + " to " + wtoken);
3836 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 // Transfer the starting window over to the new
3839 // token.
3840 wtoken.startingData = ttoken.startingData;
3841 wtoken.startingView = ttoken.startingView;
3842 wtoken.startingWindow = startingWindow;
3843 ttoken.startingData = null;
3844 ttoken.startingView = null;
3845 ttoken.startingWindow = null;
3846 ttoken.startingMoved = true;
3847 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003848 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003850 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003851 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003853 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003854 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3855 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003856 ttoken.windows.remove(startingWindow);
3857 ttoken.allAppWindows.remove(startingWindow);
3858 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 // Propagate other interesting state between the
3861 // tokens. If the old token is displayed, we should
3862 // immediately force the new one to be displayed. If
3863 // it is animating, we need to move that animation to
3864 // the new one.
3865 if (ttoken.allDrawn) {
3866 wtoken.allDrawn = true;
3867 }
3868 if (ttoken.firstWindowDrawn) {
3869 wtoken.firstWindowDrawn = true;
3870 }
3871 if (!ttoken.hidden) {
3872 wtoken.hidden = false;
3873 wtoken.hiddenRequested = false;
3874 wtoken.willBeHidden = false;
3875 }
3876 if (wtoken.clientHidden != ttoken.clientHidden) {
3877 wtoken.clientHidden = ttoken.clientHidden;
3878 wtoken.sendAppVisibilityToClients();
3879 }
3880 if (ttoken.animation != null) {
3881 wtoken.animation = ttoken.animation;
3882 wtoken.animating = ttoken.animating;
3883 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3884 ttoken.animation = null;
3885 ttoken.animLayerAdjustment = 0;
3886 wtoken.updateLayers();
3887 ttoken.updateLayers();
3888 }
Romain Guy06882f82009-06-10 13:36:04 -07003889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003891 mLayoutNeeded = true;
3892 performLayoutAndPlaceSurfacesLocked();
3893 Binder.restoreCallingIdentity(origId);
3894 return;
3895 } else if (ttoken.startingData != null) {
3896 // The previous app was getting ready to show a
3897 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003898 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 "Moving pending starting from " + ttoken
3900 + " to " + wtoken);
3901 wtoken.startingData = ttoken.startingData;
3902 ttoken.startingData = null;
3903 ttoken.startingMoved = true;
3904 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3905 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3906 // want to process the message ASAP, before any other queued
3907 // messages.
3908 mH.sendMessageAtFrontOfQueue(m);
3909 return;
3910 }
3911 }
3912 }
3913
3914 // There is no existing starting window, and the caller doesn't
3915 // want us to create one, so that's it!
3916 if (!createIfNeeded) {
3917 return;
3918 }
Romain Guy06882f82009-06-10 13:36:04 -07003919
Dianne Hackborn284ac932009-08-28 10:34:25 -07003920 // If this is a translucent or wallpaper window, then don't
3921 // show a starting window -- the current effect (a full-screen
3922 // opaque starting window that fades away to the real contents
3923 // when it is ready) does not work for this.
3924 if (theme != 0) {
3925 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3926 com.android.internal.R.styleable.Window);
3927 if (ent.array.getBoolean(
3928 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3929 return;
3930 }
3931 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003932 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3933 return;
3934 }
3935 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003936 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3937 return;
3938 }
3939 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 mStartingIconInTransition = true;
3942 wtoken.startingData = new StartingData(
3943 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003944 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3946 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3947 // want to process the message ASAP, before any other queued
3948 // messages.
3949 mH.sendMessageAtFrontOfQueue(m);
3950 }
3951 }
3952
3953 public void setAppWillBeHidden(IBinder token) {
3954 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3955 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003956 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 }
3958
3959 AppWindowToken wtoken;
3960
3961 synchronized(mWindowMap) {
3962 wtoken = findAppWindowToken(token);
3963 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003964 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 -08003965 return;
3966 }
3967 wtoken.willBeHidden = true;
3968 }
3969 }
Romain Guy06882f82009-06-10 13:36:04 -07003970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3972 boolean visible, int transit, boolean performLayout) {
3973 boolean delayed = false;
3974
3975 if (wtoken.clientHidden == visible) {
3976 wtoken.clientHidden = !visible;
3977 wtoken.sendAppVisibilityToClients();
3978 }
Romain Guy06882f82009-06-10 13:36:04 -07003979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 wtoken.willBeHidden = false;
3981 if (wtoken.hidden == visible) {
3982 final int N = wtoken.allAppWindows.size();
3983 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003984 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3986 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003989
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003990 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 if (wtoken.animation == sDummyAnimation) {
3992 wtoken.animation = null;
3993 }
3994 applyAnimationLocked(wtoken, lp, transit, visible);
3995 changed = true;
3996 if (wtoken.animation != null) {
3997 delayed = runningAppAnimation = true;
3998 }
3999 }
Romain Guy06882f82009-06-10 13:36:04 -07004000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004001 for (int i=0; i<N; i++) {
4002 WindowState win = wtoken.allAppWindows.get(i);
4003 if (win == wtoken.startingWindow) {
4004 continue;
4005 }
4006
4007 if (win.isAnimating()) {
4008 delayed = true;
4009 }
Romain Guy06882f82009-06-10 13:36:04 -07004010
Joe Onorato8a9b2202010-02-26 18:56:32 -08004011 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 //win.dump(" ");
4013 if (visible) {
4014 if (!win.isVisibleNow()) {
4015 if (!runningAppAnimation) {
4016 applyAnimationLocked(win,
4017 WindowManagerPolicy.TRANSIT_ENTER, true);
4018 }
4019 changed = true;
4020 }
4021 } else if (win.isVisibleNow()) {
4022 if (!runningAppAnimation) {
4023 applyAnimationLocked(win,
4024 WindowManagerPolicy.TRANSIT_EXIT, false);
4025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 changed = true;
4027 }
4028 }
4029
4030 wtoken.hidden = wtoken.hiddenRequested = !visible;
4031 if (!visible) {
4032 unsetAppFreezingScreenLocked(wtoken, true, true);
4033 } else {
4034 // If we are being set visible, and the starting window is
4035 // not yet displayed, then make sure it doesn't get displayed.
4036 WindowState swin = wtoken.startingWindow;
4037 if (swin != null && (swin.mDrawPending
4038 || swin.mCommitDrawPending)) {
4039 swin.mPolicyVisibility = false;
4040 swin.mPolicyVisibilityAfterAnim = false;
4041 }
4042 }
Romain Guy06882f82009-06-10 13:36:04 -07004043
Joe Onorato8a9b2202010-02-26 18:56:32 -08004044 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4046 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004047
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004048 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004050 if (performLayout) {
4051 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
4052 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07004053 } else {
4054 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004056 }
4057 }
4058
4059 if (wtoken.animation != null) {
4060 delayed = true;
4061 }
Romain Guy06882f82009-06-10 13:36:04 -07004062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 return delayed;
4064 }
4065
4066 public void setAppVisibility(IBinder token, boolean visible) {
4067 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4068 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004069 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004070 }
4071
4072 AppWindowToken wtoken;
4073
4074 synchronized(mWindowMap) {
4075 wtoken = findAppWindowToken(token);
4076 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004077 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 return;
4079 }
4080
4081 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004082 RuntimeException e = null;
4083 if (!HIDE_STACK_CRAWLS) {
4084 e = new RuntimeException();
4085 e.fillInStackTrace();
4086 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004087 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 + "): mNextAppTransition=" + mNextAppTransition
4089 + " hidden=" + wtoken.hidden
4090 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4091 }
Romain Guy06882f82009-06-10 13:36:04 -07004092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 // If we are preparing an app transition, then delay changing
4094 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004095 if (!mDisplayFrozen && mPolicy.isScreenOn()
4096 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 // Already in requested state, don't do anything more.
4098 if (wtoken.hiddenRequested != visible) {
4099 return;
4100 }
4101 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004102
Joe Onorato8a9b2202010-02-26 18:56:32 -08004103 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 TAG, "Setting dummy animation on: " + wtoken);
4105 wtoken.setDummyAnimation();
4106 mOpeningApps.remove(wtoken);
4107 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004108 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 wtoken.inPendingTransaction = true;
4110 if (visible) {
4111 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 wtoken.startingDisplayed = false;
4113 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004114
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004115 // If the token is currently hidden (should be the
4116 // common case), then we need to set up to wait for
4117 // its windows to be ready.
4118 if (wtoken.hidden) {
4119 wtoken.allDrawn = false;
4120 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004121
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004122 if (wtoken.clientHidden) {
4123 // In the case where we are making an app visible
4124 // but holding off for a transition, we still need
4125 // to tell the client to make its windows visible so
4126 // they get drawn. Otherwise, we will wait on
4127 // performing the transition until all windows have
4128 // been drawn, they never will be, and we are sad.
4129 wtoken.clientHidden = false;
4130 wtoken.sendAppVisibilityToClients();
4131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004132 }
4133 } else {
4134 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004135
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004136 // If the token is currently visible (should be the
4137 // common case), then set up to wait for it to be hidden.
4138 if (!wtoken.hidden) {
4139 wtoken.waitingToHide = true;
4140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 }
4142 return;
4143 }
Romain Guy06882f82009-06-10 13:36:04 -07004144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004146 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 wtoken.updateReportedVisibilityLocked();
4148 Binder.restoreCallingIdentity(origId);
4149 }
4150 }
4151
4152 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4153 boolean unfreezeSurfaceNow, boolean force) {
4154 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004155 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004156 + " force=" + force);
4157 final int N = wtoken.allAppWindows.size();
4158 boolean unfrozeWindows = false;
4159 for (int i=0; i<N; i++) {
4160 WindowState w = wtoken.allAppWindows.get(i);
4161 if (w.mAppFreezing) {
4162 w.mAppFreezing = false;
4163 if (w.mSurface != null && !w.mOrientationChanging) {
4164 w.mOrientationChanging = true;
4165 }
4166 unfrozeWindows = true;
4167 }
4168 }
4169 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004170 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 wtoken.freezingScreen = false;
4172 mAppsFreezingScreen--;
4173 }
4174 if (unfreezeSurfaceNow) {
4175 if (unfrozeWindows) {
4176 mLayoutNeeded = true;
4177 performLayoutAndPlaceSurfacesLocked();
4178 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004179 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 }
4181 }
4182 }
Romain Guy06882f82009-06-10 13:36:04 -07004183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4185 int configChanges) {
4186 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004187 RuntimeException e = null;
4188 if (!HIDE_STACK_CRAWLS) {
4189 e = new RuntimeException();
4190 e.fillInStackTrace();
4191 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004192 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 + ": hidden=" + wtoken.hidden + " freezing="
4194 + wtoken.freezingScreen, e);
4195 }
4196 if (!wtoken.hiddenRequested) {
4197 if (!wtoken.freezingScreen) {
4198 wtoken.freezingScreen = true;
4199 mAppsFreezingScreen++;
4200 if (mAppsFreezingScreen == 1) {
4201 startFreezingDisplayLocked();
4202 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4203 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4204 5000);
4205 }
4206 }
4207 final int N = wtoken.allAppWindows.size();
4208 for (int i=0; i<N; i++) {
4209 WindowState w = wtoken.allAppWindows.get(i);
4210 w.mAppFreezing = true;
4211 }
4212 }
4213 }
Romain Guy06882f82009-06-10 13:36:04 -07004214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 public void startAppFreezingScreen(IBinder token, int configChanges) {
4216 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4217 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004218 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 }
4220
4221 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004222 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004223 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 return;
4225 }
Romain Guy06882f82009-06-10 13:36:04 -07004226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004227 AppWindowToken wtoken = findAppWindowToken(token);
4228 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004229 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 return;
4231 }
4232 final long origId = Binder.clearCallingIdentity();
4233 startAppFreezingScreenLocked(wtoken, configChanges);
4234 Binder.restoreCallingIdentity(origId);
4235 }
4236 }
Romain Guy06882f82009-06-10 13:36:04 -07004237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 public void stopAppFreezingScreen(IBinder token, boolean force) {
4239 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4240 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004241 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243
4244 synchronized(mWindowMap) {
4245 AppWindowToken wtoken = findAppWindowToken(token);
4246 if (wtoken == null || wtoken.appToken == null) {
4247 return;
4248 }
4249 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004250 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4252 unsetAppFreezingScreenLocked(wtoken, true, force);
4253 Binder.restoreCallingIdentity(origId);
4254 }
4255 }
Romain Guy06882f82009-06-10 13:36:04 -07004256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 public void removeAppToken(IBinder token) {
4258 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4259 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004260 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 }
4262
4263 AppWindowToken wtoken = null;
4264 AppWindowToken startingToken = null;
4265 boolean delayed = false;
4266
4267 final long origId = Binder.clearCallingIdentity();
4268 synchronized(mWindowMap) {
4269 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004270 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004271 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004272 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 wtoken.inPendingTransaction = false;
4274 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004275 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 if (mClosingApps.contains(wtoken)) {
4277 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004278 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004280 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 delayed = true;
4282 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004283 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 TAG, "Removing app " + wtoken + " delayed=" + delayed
4285 + " animation=" + wtoken.animation
4286 + " animating=" + wtoken.animating);
4287 if (delayed) {
4288 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004289 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4290 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004292 } else {
4293 // Make sure there is no animation running on this token,
4294 // so any windows associated with it will be removed as
4295 // soon as their animations are complete
4296 wtoken.animation = null;
4297 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004299 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4300 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 mAppTokens.remove(wtoken);
4302 wtoken.removed = true;
4303 if (wtoken.startingData != null) {
4304 startingToken = wtoken;
4305 }
4306 unsetAppFreezingScreenLocked(wtoken, true, true);
4307 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004308 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004309 mFocusedApp = null;
4310 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004311 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 }
4313 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004314 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 }
Romain Guy06882f82009-06-10 13:36:04 -07004316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004317 if (!delayed && wtoken != null) {
4318 wtoken.updateReportedVisibilityLocked();
4319 }
4320 }
4321 Binder.restoreCallingIdentity(origId);
4322
4323 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004324 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 + startingToken + ": app token removed");
4326 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4327 mH.sendMessage(m);
4328 }
4329 }
4330
4331 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4332 final int NW = token.windows.size();
4333 for (int i=0; i<NW; i++) {
4334 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004335 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004337 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 int j = win.mChildWindows.size();
4339 while (j > 0) {
4340 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004341 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004342 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004343 "Tmp removing child window " + cwin);
4344 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 }
4346 }
4347 return NW > 0;
4348 }
4349
4350 void dumpAppTokensLocked() {
4351 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004352 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 }
4354 }
Romain Guy06882f82009-06-10 13:36:04 -07004355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 void dumpWindowsLocked() {
4357 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004358 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 }
4360 }
Romain Guy06882f82009-06-10 13:36:04 -07004361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 private int findWindowOffsetLocked(int tokenPos) {
4363 final int NW = mWindows.size();
4364
4365 if (tokenPos >= mAppTokens.size()) {
4366 int i = NW;
4367 while (i > 0) {
4368 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004369 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004370 if (win.getAppToken() != null) {
4371 return i+1;
4372 }
4373 }
4374 }
4375
4376 while (tokenPos > 0) {
4377 // Find the first app token below the new position that has
4378 // a window displayed.
4379 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004380 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004382 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004383 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004384 "Skipping token -- currently sending to bottom");
4385 tokenPos--;
4386 continue;
4387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 int i = wtoken.windows.size();
4389 while (i > 0) {
4390 i--;
4391 WindowState win = wtoken.windows.get(i);
4392 int j = win.mChildWindows.size();
4393 while (j > 0) {
4394 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004395 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004396 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 for (int pos=NW-1; pos>=0; pos--) {
4398 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004399 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 "Found child win @" + (pos+1));
4401 return pos+1;
4402 }
4403 }
4404 }
4405 }
4406 for (int pos=NW-1; pos>=0; pos--) {
4407 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004408 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 return pos+1;
4410 }
4411 }
4412 }
4413 tokenPos--;
4414 }
4415
4416 return 0;
4417 }
4418
4419 private final int reAddWindowLocked(int index, WindowState win) {
4420 final int NCW = win.mChildWindows.size();
4421 boolean added = false;
4422 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004423 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004425 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004426 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004427 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 mWindows.add(index, win);
4429 index++;
4430 added = true;
4431 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004432 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004433 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004434 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 mWindows.add(index, cwin);
4436 index++;
4437 }
4438 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004439 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004440 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004441 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 mWindows.add(index, win);
4443 index++;
4444 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004445 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 return index;
4447 }
Romain Guy06882f82009-06-10 13:36:04 -07004448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4450 final int NW = token.windows.size();
4451 for (int i=0; i<NW; i++) {
4452 index = reAddWindowLocked(index, token.windows.get(i));
4453 }
4454 return index;
4455 }
4456
4457 public void moveAppToken(int index, IBinder token) {
4458 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4459 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004460 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 }
4462
4463 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004464 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 if (DEBUG_REORDER) dumpAppTokensLocked();
4466 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004467 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4468 "Start moving token " + wtoken + " initially at "
4469 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004471 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 + token + " (" + wtoken + ")");
4473 return;
4474 }
4475 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004476 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004477 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004480 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004481 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 if (DEBUG_REORDER) dumpWindowsLocked();
4483 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004484 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 if (DEBUG_REORDER) dumpWindowsLocked();
4486 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004487 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 if (DEBUG_REORDER) dumpWindowsLocked();
4489 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 mLayoutNeeded = true;
4491 performLayoutAndPlaceSurfacesLocked();
4492 }
4493 Binder.restoreCallingIdentity(origId);
4494 }
4495 }
4496
4497 private void removeAppTokensLocked(List<IBinder> tokens) {
4498 // XXX This should be done more efficiently!
4499 // (take advantage of the fact that both lists should be
4500 // ordered in the same way.)
4501 int N = tokens.size();
4502 for (int i=0; i<N; i++) {
4503 IBinder token = tokens.get(i);
4504 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004505 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4506 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004508 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 + token + " (" + wtoken + ")");
4510 i--;
4511 N--;
4512 }
4513 }
4514 }
4515
Dianne Hackborna8f60182009-09-01 19:01:50 -07004516 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4517 boolean updateFocusAndLayout) {
4518 // First remove all of the windows from the list.
4519 tmpRemoveAppWindowsLocked(wtoken);
4520
4521 // Where to start adding?
4522 int pos = findWindowOffsetLocked(tokenPos);
4523
4524 // And now add them back at the correct place.
4525 pos = reAddAppWindowsLocked(pos, wtoken);
4526
4527 if (updateFocusAndLayout) {
4528 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4529 assignLayersLocked();
4530 }
4531 mLayoutNeeded = true;
4532 performLayoutAndPlaceSurfacesLocked();
4533 }
4534 }
4535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4537 // First remove all of the windows from the list.
4538 final int N = tokens.size();
4539 int i;
4540 for (i=0; i<N; i++) {
4541 WindowToken token = mTokenMap.get(tokens.get(i));
4542 if (token != null) {
4543 tmpRemoveAppWindowsLocked(token);
4544 }
4545 }
4546
4547 // Where to start adding?
4548 int pos = findWindowOffsetLocked(tokenPos);
4549
4550 // And now add them back at the correct place.
4551 for (i=0; i<N; i++) {
4552 WindowToken token = mTokenMap.get(tokens.get(i));
4553 if (token != null) {
4554 pos = reAddAppWindowsLocked(pos, token);
4555 }
4556 }
4557
Dianne Hackborna8f60182009-09-01 19:01:50 -07004558 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4559 assignLayersLocked();
4560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 mLayoutNeeded = true;
4562 performLayoutAndPlaceSurfacesLocked();
4563
4564 //dump();
4565 }
4566
4567 public void moveAppTokensToTop(List<IBinder> tokens) {
4568 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4569 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004570 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 }
4572
4573 final long origId = Binder.clearCallingIdentity();
4574 synchronized(mWindowMap) {
4575 removeAppTokensLocked(tokens);
4576 final int N = tokens.size();
4577 for (int i=0; i<N; i++) {
4578 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4579 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004580 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4581 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004583 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004584 mToTopApps.remove(wt);
4585 mToBottomApps.remove(wt);
4586 mToTopApps.add(wt);
4587 wt.sendingToBottom = false;
4588 wt.sendingToTop = true;
4589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 }
4591 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004592
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004593 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004594 moveAppWindowsLocked(tokens, mAppTokens.size());
4595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 }
4597 Binder.restoreCallingIdentity(origId);
4598 }
4599
4600 public void moveAppTokensToBottom(List<IBinder> tokens) {
4601 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4602 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004603 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 }
4605
4606 final long origId = Binder.clearCallingIdentity();
4607 synchronized(mWindowMap) {
4608 removeAppTokensLocked(tokens);
4609 final int N = tokens.size();
4610 int pos = 0;
4611 for (int i=0; i<N; i++) {
4612 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4613 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004614 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4615 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004617 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004618 mToTopApps.remove(wt);
4619 mToBottomApps.remove(wt);
4620 mToBottomApps.add(i, wt);
4621 wt.sendingToTop = false;
4622 wt.sendingToBottom = true;
4623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 pos++;
4625 }
4626 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004627
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004628 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004629 moveAppWindowsLocked(tokens, 0);
4630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 }
4632 Binder.restoreCallingIdentity(origId);
4633 }
4634
4635 // -------------------------------------------------------------
4636 // Misc IWindowSession methods
4637 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004638
Jim Miller284b62e2010-06-08 14:27:42 -07004639 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004640 {
Jim Miller284b62e2010-06-08 14:27:42 -07004641 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4642 // called before DevicePolicyManagerService has started.
4643 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4644 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4645 Context.DEVICE_POLICY_SERVICE);
4646 if (dpm != null) {
4647 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4648 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4649 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4650 }
Jim Millerd6b57052010-06-07 17:52:42 -07004651 }
Jim Miller284b62e2010-06-08 14:27:42 -07004652 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004653 }
4654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004656 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 != PackageManager.PERMISSION_GRANTED) {
4658 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4659 }
Jim Millerd6b57052010-06-07 17:52:42 -07004660
Jim Miller284b62e2010-06-08 14:27:42 -07004661 synchronized (mKeyguardTokenWatcher) {
4662 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 }
4665
4666 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004667 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004668 != PackageManager.PERMISSION_GRANTED) {
4669 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004671
Jim Miller284b62e2010-06-08 14:27:42 -07004672 synchronized (mKeyguardTokenWatcher) {
4673 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004674
Jim Miller284b62e2010-06-08 14:27:42 -07004675 if (!mKeyguardTokenWatcher.isAcquired()) {
4676 // If we are the last one to reenable the keyguard wait until
4677 // we have actually finished reenabling until returning.
4678 // It is possible that reenableKeyguard() can be called before
4679 // the previous disableKeyguard() is handled, in which case
4680 // neither mKeyguardTokenWatcher.acquired() or released() would
4681 // be called. In that case mKeyguardDisabled will be false here
4682 // and we have nothing to wait for.
4683 while (mKeyguardDisabled) {
4684 try {
4685 mKeyguardTokenWatcher.wait();
4686 } catch (InterruptedException e) {
4687 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 }
4689 }
4690 }
4691 }
4692 }
4693
4694 /**
4695 * @see android.app.KeyguardManager#exitKeyguardSecurely
4696 */
4697 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004698 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004699 != PackageManager.PERMISSION_GRANTED) {
4700 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4701 }
4702 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4703 public void onKeyguardExitResult(boolean success) {
4704 try {
4705 callback.onKeyguardExitResult(success);
4706 } catch (RemoteException e) {
4707 // Client has died, we don't care.
4708 }
4709 }
4710 });
4711 }
4712
4713 public boolean inKeyguardRestrictedInputMode() {
4714 return mPolicy.inKeyguardRestrictedKeyInputMode();
4715 }
Romain Guy06882f82009-06-10 13:36:04 -07004716
Dianne Hackbornffa42482009-09-23 22:20:11 -07004717 public void closeSystemDialogs(String reason) {
4718 synchronized(mWindowMap) {
4719 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004720 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004721 if (w.mSurface != null) {
4722 try {
4723 w.mClient.closeSystemDialogs(reason);
4724 } catch (RemoteException e) {
4725 }
4726 }
4727 }
4728 }
4729 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 static float fixScale(float scale) {
4732 if (scale < 0) scale = 0;
4733 else if (scale > 20) scale = 20;
4734 return Math.abs(scale);
4735 }
Romain Guy06882f82009-06-10 13:36:04 -07004736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 public void setAnimationScale(int which, float scale) {
4738 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4739 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004740 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 }
4742
4743 if (scale < 0) scale = 0;
4744 else if (scale > 20) scale = 20;
4745 scale = Math.abs(scale);
4746 switch (which) {
4747 case 0: mWindowAnimationScale = fixScale(scale); break;
4748 case 1: mTransitionAnimationScale = fixScale(scale); break;
4749 }
Romain Guy06882f82009-06-10 13:36:04 -07004750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 // Persist setting
4752 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4753 }
Romain Guy06882f82009-06-10 13:36:04 -07004754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 public void setAnimationScales(float[] scales) {
4756 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4757 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004758 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 }
4760
4761 if (scales != null) {
4762 if (scales.length >= 1) {
4763 mWindowAnimationScale = fixScale(scales[0]);
4764 }
4765 if (scales.length >= 2) {
4766 mTransitionAnimationScale = fixScale(scales[1]);
4767 }
4768 }
Romain Guy06882f82009-06-10 13:36:04 -07004769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 // Persist setting
4771 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4772 }
Romain Guy06882f82009-06-10 13:36:04 -07004773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 public float getAnimationScale(int which) {
4775 switch (which) {
4776 case 0: return mWindowAnimationScale;
4777 case 1: return mTransitionAnimationScale;
4778 }
4779 return 0;
4780 }
Romain Guy06882f82009-06-10 13:36:04 -07004781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004782 public float[] getAnimationScales() {
4783 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4784 }
Romain Guy06882f82009-06-10 13:36:04 -07004785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 public int getSwitchState(int sw) {
4787 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4788 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004789 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004791 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 }
Romain Guy06882f82009-06-10 13:36:04 -07004793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 public int getSwitchStateForDevice(int devid, int sw) {
4795 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4796 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004797 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004798 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004799 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 }
Romain Guy06882f82009-06-10 13:36:04 -07004801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 public int getScancodeState(int sw) {
4803 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4804 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004805 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004807 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 }
Romain Guy06882f82009-06-10 13:36:04 -07004809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004810 public int getScancodeStateForDevice(int devid, int sw) {
4811 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4812 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004813 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004815 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004816 }
Romain Guy06882f82009-06-10 13:36:04 -07004817
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004818 public int getTrackballScancodeState(int sw) {
4819 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4820 "getTrackballScancodeState()")) {
4821 throw new SecurityException("Requires READ_INPUT_STATE permission");
4822 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004823 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004824 }
4825
4826 public int getDPadScancodeState(int sw) {
4827 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4828 "getDPadScancodeState()")) {
4829 throw new SecurityException("Requires READ_INPUT_STATE permission");
4830 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004831 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004832 }
4833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 public int getKeycodeState(int sw) {
4835 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4836 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004837 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004839 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 }
Romain Guy06882f82009-06-10 13:36:04 -07004841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 public int getKeycodeStateForDevice(int devid, int sw) {
4843 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4844 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004845 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004847 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
Romain Guy06882f82009-06-10 13:36:04 -07004849
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004850 public int getTrackballKeycodeState(int sw) {
4851 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4852 "getTrackballKeycodeState()")) {
4853 throw new SecurityException("Requires READ_INPUT_STATE permission");
4854 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004855 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004856 }
4857
4858 public int getDPadKeycodeState(int sw) {
4859 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4860 "getDPadKeycodeState()")) {
4861 throw new SecurityException("Requires READ_INPUT_STATE permission");
4862 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004863 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004864 }
Jeff Browna41ca772010-08-11 14:46:32 -07004865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004867 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004868 }
Romain Guy06882f82009-06-10 13:36:04 -07004869
Jeff Browna41ca772010-08-11 14:46:32 -07004870 public InputChannel monitorInput(String inputChannelName) {
4871 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4872 "monitorInput()")) {
4873 throw new SecurityException("Requires READ_INPUT_STATE permission");
4874 }
4875 return mInputManager.monitorInput(inputChannelName);
4876 }
4877
Jeff Brown8d608662010-08-30 03:02:23 -07004878 public InputDevice getInputDevice(int deviceId) {
4879 return mInputManager.getInputDevice(deviceId);
4880 }
4881
4882 public int[] getInputDeviceIds() {
4883 return mInputManager.getInputDeviceIds();
4884 }
4885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 public void enableScreenAfterBoot() {
4887 synchronized(mWindowMap) {
4888 if (mSystemBooted) {
4889 return;
4890 }
4891 mSystemBooted = true;
4892 }
Romain Guy06882f82009-06-10 13:36:04 -07004893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 performEnableScreen();
4895 }
Romain Guy06882f82009-06-10 13:36:04 -07004896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 public void enableScreenIfNeededLocked() {
4898 if (mDisplayEnabled) {
4899 return;
4900 }
4901 if (!mSystemBooted) {
4902 return;
4903 }
4904 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4905 }
Romain Guy06882f82009-06-10 13:36:04 -07004906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 public void performEnableScreen() {
4908 synchronized(mWindowMap) {
4909 if (mDisplayEnabled) {
4910 return;
4911 }
4912 if (!mSystemBooted) {
4913 return;
4914 }
Romain Guy06882f82009-06-10 13:36:04 -07004915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 // Don't enable the screen until all existing windows
4917 // have been drawn.
4918 final int N = mWindows.size();
4919 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004920 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004921 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 return;
4923 }
4924 }
Romain Guy06882f82009-06-10 13:36:04 -07004925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 mDisplayEnabled = true;
4927 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004928 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 StringWriter sw = new StringWriter();
4930 PrintWriter pw = new PrintWriter(sw);
4931 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004932 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 }
4934 try {
4935 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4936 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004937 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 Parcel data = Parcel.obtain();
4939 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4940 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4941 data, null, 0);
4942 data.recycle();
4943 }
4944 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004945 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 }
4947 }
Romain Guy06882f82009-06-10 13:36:04 -07004948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004949 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004952 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4953 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 }
Romain Guy06882f82009-06-10 13:36:04 -07004955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 public void setInTouchMode(boolean mode) {
4957 synchronized(mWindowMap) {
4958 mInTouchMode = mode;
4959 }
4960 }
4961
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004962 // TODO: more accounting of which pid(s) turned it on, keep count,
4963 // only allow disables from pids which have count on, etc.
4964 public void showStrictModeViolation(boolean on) {
4965 int pid = Binder.getCallingPid();
4966 synchronized(mWindowMap) {
4967 // Ignoring requests to enable the red border from clients
4968 // which aren't on screen. (e.g. Broadcast Receivers in
4969 // the background..)
4970 if (on) {
4971 boolean isVisible = false;
4972 for (WindowState ws : mWindows) {
4973 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4974 isVisible = true;
4975 break;
4976 }
4977 }
4978 if (!isVisible) {
4979 return;
4980 }
4981 }
4982
4983 Surface.openTransaction();
4984 if (mStrictModeFlash == null) {
4985 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4986 }
4987 mStrictModeFlash.setVisibility(on);
4988 Surface.closeTransaction();
4989 }
4990 }
4991
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004992 public void setStrictModeVisualIndicatorPreference(String value) {
4993 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4994 }
4995
Dianne Hackbornd2835932010-12-13 16:28:46 -08004996 public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004997 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4998 "screenshotApplications()")) {
4999 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5000 }
5001
5002 Bitmap rawss;
5003
Dianne Hackbornd2835932010-12-13 16:28:46 -08005004 int maxLayer = 0;
5005 boolean foundApp;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005006 final Rect frame = new Rect();
5007
5008 float scale;
5009 int sw, sh, dw, dh;
5010 int rot;
5011
5012 synchronized(mWindowMap) {
5013 long ident = Binder.clearCallingIdentity();
5014
5015 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
5016 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
5017 + TYPE_LAYER_OFFSET;
5018 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5019
5020 // Figure out the part of the screen that is actually the app.
5021 for (int i=0; i<mWindows.size(); i++) {
5022 WindowState ws = mWindows.get(i);
5023 if (ws.mSurface == null) {
5024 continue;
5025 }
5026 if (ws.mLayer >= aboveAppLayer) {
5027 break;
5028 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005029 if (appToken != null && (ws.mAppToken == null
5030 || ws.mAppToken.token != appToken)) {
5031 continue;
5032 }
5033 if (maxLayer < ws.mAnimLayer) {
5034 maxLayer = ws.mAnimLayer;
5035 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005036 final Rect wf = ws.mFrame;
5037 final Rect cr = ws.mContentInsets;
5038 int left = wf.left + cr.left;
5039 int top = wf.top + cr.top;
5040 int right = wf.right - cr.right;
5041 int bottom = wf.bottom - cr.bottom;
5042 frame.union(left, top, right, bottom);
5043 }
5044 Binder.restoreCallingIdentity(ident);
5045
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005046 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005047 return null;
5048 }
5049
5050 // The screenshot API does not apply the current screen rotation.
5051 rot = mDisplay.getRotation();
5052 int fw = frame.width();
5053 int fh = frame.height();
5054
5055 // First try reducing to fit in x dimension.
5056 scale = maxWidth/(float)fw;
5057 sw = maxWidth;
5058 sh = (int)(fh*scale);
5059 if (sh > maxHeight) {
5060 // y dimension became too long; constrain by that.
5061 scale = maxHeight/(float)fh;
5062 sw = (int)(fw*scale);
5063 sh = maxHeight;
5064 }
5065
5066 // The screen shot will contain the entire screen.
5067 dw = (int)(mDisplay.getWidth()*scale);
5068 dh = (int)(mDisplay.getHeight()*scale);
5069 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5070 int tmp = dw;
5071 dw = dh;
5072 dh = tmp;
5073 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5074 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005075 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005076 }
5077
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005078 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005079 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
5080 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005081 return null;
5082 }
5083
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005084 Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
5085 Matrix matrix = new Matrix();
5086 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5087 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
5088 Canvas canvas = new Canvas(bm);
5089 canvas.drawBitmap(rawss, matrix, null);
5090
5091 rawss.recycle();
5092 return bm;
5093 }
5094
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005095 public void freezeRotation() {
5096 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5097 "setRotation()")) {
5098 throw new SecurityException("Requires SET_ORIENTATION permission");
5099 }
5100
5101 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
5102 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5103 }
5104
5105 public void thawRotation() {
5106 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5107 "setRotation()")) {
5108 throw new SecurityException("Requires SET_ORIENTATION permission");
5109 }
5110
5111 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
5112 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5113 }
5114
Romain Guy06882f82009-06-10 13:36:04 -07005115 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005116 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005118 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005119 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120 }
5121
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005122 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 }
Romain Guy06882f82009-06-10 13:36:04 -07005124
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005125 public void setRotationUnchecked(int rotation,
5126 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005127 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07005129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005130 long origId = Binder.clearCallingIdentity();
5131 boolean changed;
5132 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005133 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 }
Romain Guy06882f82009-06-10 13:36:04 -07005135
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005136 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 sendNewConfiguration();
5138 }
Romain Guy06882f82009-06-10 13:36:04 -07005139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 Binder.restoreCallingIdentity(origId);
5141 }
Romain Guy06882f82009-06-10 13:36:04 -07005142
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005143 /**
5144 * Apply a new rotation to the screen, respecting the requests of
5145 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
5146 * re-evaluate the desired rotation.
5147 *
5148 * Returns null if the rotation has been changed. In this case YOU
5149 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
5150 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005151 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
Christopher Tateccd24de2011-01-12 15:02:55 -08005152 if (mDragState != null) {
5153 // Potential rotation during a drag. Don't do the rotation now, but make
5154 // a note to perform the rotation later.
5155 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation during drag");
5156 mDragState.setDeferredRotation(rotation, animFlags);
5157 return false;
5158 }
5159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 boolean changed;
5161 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
5162 rotation = mRequestedRotation;
5163 } else {
5164 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07005165 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005166 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005167 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07005168 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005170 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07005172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005173 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005174 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 "Rotation changed to " + rotation
5176 + " from " + mRotation
5177 + " (forceApp=" + mForcedAppOrientation
5178 + ", req=" + mRequestedRotation + ")");
5179 mRotation = rotation;
5180 mWindowsFreezingScreen = true;
5181 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5182 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
5183 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005184 mWaitingForConfig = true;
5185 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005187 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005188 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005189 if (mDisplayEnabled) {
Dianne Hackborna1111872010-11-23 20:55:11 -08005190 if (CUSTOM_SCREEN_ROTATION) {
5191 Surface.freezeDisplay(0);
5192 Surface.openTransaction();
5193 if (mScreenRotationAnimation != null) {
5194 mScreenRotationAnimation.setRotation(rotation);
5195 }
5196 Surface.closeTransaction();
5197 Surface.setOrientation(0, rotation, animFlags);
5198 Surface.unfreezeDisplay(0);
5199 } else {
5200 Surface.setOrientation(0, rotation, animFlags);
5201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005202 }
5203 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005204 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 if (w.mSurface != null) {
5206 w.mOrientationChanging = true;
5207 }
5208 }
5209 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5210 try {
5211 mRotationWatchers.get(i).onRotationChanged(rotation);
5212 } catch (RemoteException e) {
5213 }
5214 }
5215 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005217 return changed;
5218 }
Romain Guy06882f82009-06-10 13:36:04 -07005219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 public int getRotation() {
5221 return mRotation;
5222 }
5223
5224 public int watchRotation(IRotationWatcher watcher) {
5225 final IBinder watcherBinder = watcher.asBinder();
5226 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5227 public void binderDied() {
5228 synchronized (mWindowMap) {
5229 for (int i=0; i<mRotationWatchers.size(); i++) {
5230 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005231 IRotationWatcher removed = mRotationWatchers.remove(i);
5232 if (removed != null) {
5233 removed.asBinder().unlinkToDeath(this, 0);
5234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005235 i--;
5236 }
5237 }
5238 }
5239 }
5240 };
Romain Guy06882f82009-06-10 13:36:04 -07005241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 synchronized (mWindowMap) {
5243 try {
5244 watcher.asBinder().linkToDeath(dr, 0);
5245 mRotationWatchers.add(watcher);
5246 } catch (RemoteException e) {
5247 // Client died, no cleanup needed.
5248 }
Romain Guy06882f82009-06-10 13:36:04 -07005249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 return mRotation;
5251 }
5252 }
5253
5254 /**
5255 * Starts the view server on the specified port.
5256 *
5257 * @param port The port to listener to.
5258 *
5259 * @return True if the server was successfully started, false otherwise.
5260 *
5261 * @see com.android.server.ViewServer
5262 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5263 */
5264 public boolean startViewServer(int port) {
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, "startViewServer")) {
5270 return false;
5271 }
5272
5273 if (port < 1024) {
5274 return false;
5275 }
5276
5277 if (mViewServer != null) {
5278 if (!mViewServer.isRunning()) {
5279 try {
5280 return mViewServer.start();
5281 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005282 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005283 }
5284 }
5285 return false;
5286 }
5287
5288 try {
5289 mViewServer = new ViewServer(this, port);
5290 return mViewServer.start();
5291 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005292 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 }
5294 return false;
5295 }
5296
Romain Guy06882f82009-06-10 13:36:04 -07005297 private boolean isSystemSecure() {
5298 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5299 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5300 }
5301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005302 /**
5303 * Stops the view server if it exists.
5304 *
5305 * @return True if the server stopped, false if it wasn't started or
5306 * couldn't be stopped.
5307 *
5308 * @see com.android.server.ViewServer
5309 */
5310 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005311 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 return false;
5313 }
5314
5315 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5316 return false;
5317 }
5318
5319 if (mViewServer != null) {
5320 return mViewServer.stop();
5321 }
5322 return false;
5323 }
5324
5325 /**
5326 * Indicates whether the view server is running.
5327 *
5328 * @return True if the server is running, false otherwise.
5329 *
5330 * @see com.android.server.ViewServer
5331 */
5332 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005333 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 return false;
5335 }
5336
5337 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5338 return false;
5339 }
5340
5341 return mViewServer != null && mViewServer.isRunning();
5342 }
5343
5344 /**
5345 * Lists all availble windows in the system. The listing is written in the
5346 * specified Socket's output stream with the following syntax:
5347 * windowHashCodeInHexadecimal windowName
5348 * Each line of the ouput represents a different window.
5349 *
5350 * @param client The remote client to send the listing to.
5351 * @return False if an error occured, true otherwise.
5352 */
5353 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005354 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 return false;
5356 }
5357
5358 boolean result = true;
5359
Jeff Browne33348b2010-07-15 23:54:05 -07005360 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005362 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005363 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 }
5365
5366 BufferedWriter out = null;
5367
5368 // Any uncaught exception will crash the system process
5369 try {
5370 OutputStream clientStream = client.getOutputStream();
5371 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5372
5373 final int count = windows.length;
5374 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005375 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 out.write(Integer.toHexString(System.identityHashCode(w)));
5377 out.write(' ');
5378 out.append(w.mAttrs.getTitle());
5379 out.write('\n');
5380 }
5381
5382 out.write("DONE.\n");
5383 out.flush();
5384 } catch (Exception e) {
5385 result = false;
5386 } finally {
5387 if (out != null) {
5388 try {
5389 out.close();
5390 } catch (IOException e) {
5391 result = false;
5392 }
5393 }
5394 }
5395
5396 return result;
5397 }
5398
5399 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005400 * Returns the focused window in the following format:
5401 * windowHashCodeInHexadecimal windowName
5402 *
5403 * @param client The remote client to send the listing to.
5404 * @return False if an error occurred, true otherwise.
5405 */
5406 boolean viewServerGetFocusedWindow(Socket client) {
5407 if (isSystemSecure()) {
5408 return false;
5409 }
5410
5411 boolean result = true;
5412
5413 WindowState focusedWindow = getFocusedWindow();
5414
5415 BufferedWriter out = null;
5416
5417 // Any uncaught exception will crash the system process
5418 try {
5419 OutputStream clientStream = client.getOutputStream();
5420 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5421
5422 if(focusedWindow != null) {
5423 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5424 out.write(' ');
5425 out.append(focusedWindow.mAttrs.getTitle());
5426 }
5427 out.write('\n');
5428 out.flush();
5429 } catch (Exception e) {
5430 result = false;
5431 } finally {
5432 if (out != null) {
5433 try {
5434 out.close();
5435 } catch (IOException e) {
5436 result = false;
5437 }
5438 }
5439 }
5440
5441 return result;
5442 }
5443
5444 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445 * Sends a command to a target window. The result of the command, if any, will be
5446 * written in the output stream of the specified socket.
5447 *
5448 * The parameters must follow this syntax:
5449 * windowHashcode extra
5450 *
5451 * Where XX is the length in characeters of the windowTitle.
5452 *
5453 * The first parameter is the target window. The window with the specified hashcode
5454 * will be the target. If no target can be found, nothing happens. The extra parameters
5455 * will be delivered to the target window and as parameters to the command itself.
5456 *
5457 * @param client The remote client to sent the result, if any, to.
5458 * @param command The command to execute.
5459 * @param parameters The command parameters.
5460 *
5461 * @return True if the command was successfully delivered, false otherwise. This does
5462 * not indicate whether the command itself was successful.
5463 */
5464 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005465 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 return false;
5467 }
5468
5469 boolean success = true;
5470 Parcel data = null;
5471 Parcel reply = null;
5472
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005473 BufferedWriter out = null;
5474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 // Any uncaught exception will crash the system process
5476 try {
5477 // Find the hashcode of the window
5478 int index = parameters.indexOf(' ');
5479 if (index == -1) {
5480 index = parameters.length();
5481 }
5482 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005483 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484
5485 // Extract the command's parameter after the window description
5486 if (index < parameters.length()) {
5487 parameters = parameters.substring(index + 1);
5488 } else {
5489 parameters = "";
5490 }
5491
5492 final WindowManagerService.WindowState window = findWindow(hashCode);
5493 if (window == null) {
5494 return false;
5495 }
5496
5497 data = Parcel.obtain();
5498 data.writeInterfaceToken("android.view.IWindow");
5499 data.writeString(command);
5500 data.writeString(parameters);
5501 data.writeInt(1);
5502 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5503
5504 reply = Parcel.obtain();
5505
5506 final IBinder binder = window.mClient.asBinder();
5507 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5508 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5509
5510 reply.readException();
5511
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005512 if (!client.isOutputShutdown()) {
5513 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5514 out.write("DONE\n");
5515 out.flush();
5516 }
5517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005519 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 success = false;
5521 } finally {
5522 if (data != null) {
5523 data.recycle();
5524 }
5525 if (reply != null) {
5526 reply.recycle();
5527 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005528 if (out != null) {
5529 try {
5530 out.close();
5531 } catch (IOException e) {
5532
5533 }
5534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 }
5536
5537 return success;
5538 }
5539
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005540 public void addWindowChangeListener(WindowChangeListener listener) {
5541 synchronized(mWindowMap) {
5542 mWindowChangeListeners.add(listener);
5543 }
5544 }
5545
5546 public void removeWindowChangeListener(WindowChangeListener listener) {
5547 synchronized(mWindowMap) {
5548 mWindowChangeListeners.remove(listener);
5549 }
5550 }
5551
5552 private void notifyWindowsChanged() {
5553 WindowChangeListener[] windowChangeListeners;
5554 synchronized(mWindowMap) {
5555 if(mWindowChangeListeners.isEmpty()) {
5556 return;
5557 }
5558 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5559 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5560 }
5561 int N = windowChangeListeners.length;
5562 for(int i = 0; i < N; i++) {
5563 windowChangeListeners[i].windowsChanged();
5564 }
5565 }
5566
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005567 private void notifyFocusChanged() {
5568 WindowChangeListener[] windowChangeListeners;
5569 synchronized(mWindowMap) {
5570 if(mWindowChangeListeners.isEmpty()) {
5571 return;
5572 }
5573 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5574 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5575 }
5576 int N = windowChangeListeners.length;
5577 for(int i = 0; i < N; i++) {
5578 windowChangeListeners[i].focusChanged();
5579 }
5580 }
5581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 private WindowState findWindow(int hashCode) {
5583 if (hashCode == -1) {
5584 return getFocusedWindow();
5585 }
5586
5587 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005588 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005589 final int count = windows.size();
5590
5591 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005592 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 if (System.identityHashCode(w) == hashCode) {
5594 return w;
5595 }
5596 }
5597 }
5598
5599 return null;
5600 }
5601
5602 /*
5603 * Instruct the Activity Manager to fetch the current configuration and broadcast
5604 * that to config-changed listeners if appropriate.
5605 */
5606 void sendNewConfiguration() {
5607 try {
5608 mActivityManager.updateConfiguration(null);
5609 } catch (RemoteException e) {
5610 }
5611 }
Romain Guy06882f82009-06-10 13:36:04 -07005612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 public Configuration computeNewConfiguration() {
5614 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005615 return computeNewConfigurationLocked();
5616 }
5617 }
Romain Guy06882f82009-06-10 13:36:04 -07005618
Dianne Hackbornc485a602009-03-24 22:39:49 -07005619 Configuration computeNewConfigurationLocked() {
5620 Configuration config = new Configuration();
5621 if (!computeNewConfigurationLocked(config)) {
5622 return null;
5623 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005624 return config;
5625 }
Romain Guy06882f82009-06-10 13:36:04 -07005626
Dianne Hackbornc485a602009-03-24 22:39:49 -07005627 boolean computeNewConfigurationLocked(Configuration config) {
5628 if (mDisplay == null) {
5629 return false;
5630 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005631
5632 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005633
5634 // Use the effective "visual" dimensions based on current rotation
5635 final boolean rotated = (mRotation == Surface.ROTATION_90
5636 || mRotation == Surface.ROTATION_270);
5637 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5638 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5639
Dianne Hackbornc485a602009-03-24 22:39:49 -07005640 int orientation = Configuration.ORIENTATION_SQUARE;
5641 if (dw < dh) {
5642 orientation = Configuration.ORIENTATION_PORTRAIT;
5643 } else if (dw > dh) {
5644 orientation = Configuration.ORIENTATION_LANDSCAPE;
5645 }
5646 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005647
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005648 DisplayMetrics dm = new DisplayMetrics();
5649 mDisplay.getMetrics(dm);
5650 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5651
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005652 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005653 // Note we only do this once because at this point we don't
5654 // expect the screen to change in this way at runtime, and want
5655 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005656 int longSize = dw;
5657 int shortSize = dh;
5658 if (longSize < shortSize) {
5659 int tmp = longSize;
5660 longSize = shortSize;
5661 shortSize = tmp;
5662 }
5663 longSize = (int)(longSize/dm.density);
5664 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005665
Dianne Hackborn723738c2009-06-25 19:48:04 -07005666 // These semi-magic numbers define our compatibility modes for
5667 // applications with different screens. Don't change unless you
5668 // make sure to test lots and lots of apps!
5669 if (longSize < 470) {
5670 // This is shorter than an HVGA normal density screen (which
5671 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005672 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5673 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005674 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005675 // What size is this screen screen?
5676 if (longSize >= 800 && shortSize >= 600) {
5677 // SVGA or larger screens at medium density are the point
5678 // at which we consider it to be an extra large screen.
5679 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005680 } else if (longSize >= 530 && shortSize >= 400) {
5681 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005682 // at which we consider it to be a large screen.
5683 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5684 } else {
5685 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005686
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005687 // If this screen is wider than normal HVGA, or taller
5688 // than FWVGA, then for old apps we want to run in size
5689 // compatibility mode.
5690 if (shortSize > 321 || longSize > 570) {
5691 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5692 }
5693 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005694
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005695 // Is this a long screen?
5696 if (((longSize*3)/5) >= (shortSize-1)) {
5697 // Anything wider than WVGA (5:3) is considering to be long.
5698 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5699 } else {
5700 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5701 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005702 }
5703 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005704 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005705
Dianne Hackbornc485a602009-03-24 22:39:49 -07005706 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5707 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5708 mPolicy.adjustConfigurationLw(config);
5709 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005711
5712 // -------------------------------------------------------------
5713 // Drag and drop
5714 // -------------------------------------------------------------
5715
5716 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005717 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005718 if (DEBUG_DRAG) {
5719 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005720 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005721 + " asbinder=" + window.asBinder());
5722 }
5723
5724 final int callerPid = Binder.getCallingPid();
5725 final long origId = Binder.clearCallingIdentity();
5726 IBinder token = null;
5727
5728 try {
5729 synchronized (mWindowMap) {
5730 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005731 if (mDragState == null) {
5732 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5733 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5734 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005735 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005736 token = new Binder();
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005737 // TODO: preserve flags param in DragState
5738 mDragState = new DragState(token, surface, 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005739 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005740 token = mDragState.mToken = new Binder();
5741
5742 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005743 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5744 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005745 mH.sendMessageDelayed(msg, 5000);
5746 } else {
5747 Slog.w(TAG, "Drag already in progress");
5748 }
5749 } catch (Surface.OutOfResourcesException e) {
5750 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5751 if (mDragState != null) {
5752 mDragState.reset();
5753 mDragState = null;
5754 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005755 }
5756 }
5757 } finally {
5758 Binder.restoreCallingIdentity(origId);
5759 }
5760
5761 return token;
5762 }
5763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005764 // -------------------------------------------------------------
5765 // Input Events and Focus Management
5766 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005767
Jeff Brown349703e2010-06-22 01:27:15 -07005768 InputMonitor mInputMonitor = new InputMonitor();
5769
5770 /* Tracks the progress of input dispatch and ensures that input dispatch state
5771 * is kept in sync with changes in window focus, visibility, registration, and
5772 * other relevant Window Manager state transitions. */
5773 final class InputMonitor {
5774 // Current window with input focus for keys and other non-touch events. May be null.
5775 private WindowState mInputFocus;
5776
5777 // When true, prevents input dispatch from proceeding until set to false again.
5778 private boolean mInputDispatchFrozen;
5779
5780 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5781 private boolean mInputDispatchEnabled = true;
5782
5783 // Temporary list of windows information to provide to the input dispatcher.
5784 private InputWindowList mTempInputWindows = new InputWindowList();
5785
5786 // Temporary input application object to provide to the input dispatcher.
5787 private InputApplication mTempInputApplication = new InputApplication();
5788
Jeff Brownb09abc12011-01-13 21:08:27 -08005789 // Set to true when the first input device configuration change notification
5790 // is received to indicate that the input devices are ready.
5791 private final Object mInputDevicesReadyMonitor = new Object();
5792 private boolean mInputDevicesReady;
5793
Jeff Brown349703e2010-06-22 01:27:15 -07005794 /* Notifies the window manager about a broken input channel.
5795 *
5796 * Called by the InputManager.
5797 */
Jeff Brown928e0542011-01-10 11:17:36 -08005798 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
5799 if (inputWindowHandle == null) {
5800 return;
5801 }
5802
Jeff Brown349703e2010-06-22 01:27:15 -07005803 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005804 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown349703e2010-06-22 01:27:15 -07005805 Slog.i(TAG, "WINDOW DIED " + windowState);
5806 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005807 }
5808 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005809
Jeff Brown519e0242010-09-15 15:18:56 -07005810 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005811 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005812 *
5813 * Called by the InputManager.
5814 */
Jeff Brown928e0542011-01-10 11:17:36 -08005815 public long notifyANR(InputApplicationHandle inputApplicationHandle,
5816 InputWindowHandle inputWindowHandle) {
Jeff Brown519e0242010-09-15 15:18:56 -07005817 AppWindowToken appWindowToken = null;
Jeff Brown928e0542011-01-10 11:17:36 -08005818 if (inputWindowHandle != null) {
Jeff Brown519e0242010-09-15 15:18:56 -07005819 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005820 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown519e0242010-09-15 15:18:56 -07005821 if (windowState != null) {
5822 Slog.i(TAG, "Input event dispatching timed out sending to "
5823 + windowState.mAttrs.getTitle());
5824 appWindowToken = windowState.mAppToken;
5825 }
Jeff Brown349703e2010-06-22 01:27:15 -07005826 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005827 }
5828
Jeff Brown928e0542011-01-10 11:17:36 -08005829 if (appWindowToken == null && inputApplicationHandle != null) {
5830 appWindowToken = inputApplicationHandle.appWindowToken;
Jeff Brown519e0242010-09-15 15:18:56 -07005831 Slog.i(TAG, "Input event dispatching timed out sending to application "
5832 + appWindowToken.stringName);
5833 }
Jeff Brown349703e2010-06-22 01:27:15 -07005834
Jeff Brown519e0242010-09-15 15:18:56 -07005835 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005836 try {
5837 // Notify the activity manager about the timeout and let it decide whether
5838 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005839 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005840 if (! abort) {
5841 // The activity manager declined to abort dispatching.
5842 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005843 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005844 }
Jeff Brown349703e2010-06-22 01:27:15 -07005845 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005846 }
5847 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005848 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005849 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005850
Chris Tatea32dcf72010-10-14 12:13:50 -07005851 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005852 final InputWindow inputWindow = windowList.add();
5853 inputWindow.inputChannel = mDragState.mServerChannel;
5854 inputWindow.name = "drag";
5855 inputWindow.layoutParamsFlags = 0;
5856 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5857 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5858 inputWindow.visible = true;
5859 inputWindow.canReceiveKeys = false;
5860 inputWindow.hasFocus = true;
5861 inputWindow.hasWallpaper = false;
5862 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07005863 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07005864 inputWindow.ownerPid = Process.myPid();
5865 inputWindow.ownerUid = Process.myUid();
5866
5867 // The drag window covers the entire display
5868 inputWindow.frameLeft = 0;
5869 inputWindow.frameTop = 0;
5870 inputWindow.frameRight = mDisplay.getWidth();
5871 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005872
Christopher Tatea53146c2010-09-07 11:57:52 -07005873 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5874 inputWindow.visibleFrameTop = inputWindow.frameTop;
5875 inputWindow.visibleFrameRight = inputWindow.frameRight;
5876 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5877
5878 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5879 inputWindow.touchableAreaTop = inputWindow.frameTop;
5880 inputWindow.touchableAreaRight = inputWindow.frameRight;
5881 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5882 }
5883
Jeff Brown349703e2010-06-22 01:27:15 -07005884 /* Updates the cached window information provided to the input dispatcher. */
5885 public void updateInputWindowsLw() {
5886 // Populate the input window list with information about all of the windows that
5887 // could potentially receive input.
5888 // As an optimization, we could try to prune the list of windows but this turns
5889 // out to be difficult because only the native code knows for sure which window
5890 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005891 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005892
5893 // If there's a drag in flight, provide a pseudowindow to catch drag input
5894 final boolean inDrag = (mDragState != null);
5895 if (inDrag) {
5896 if (DEBUG_DRAG) {
5897 Log.d(TAG, "Inserting drag window");
5898 }
Chris Tatea32dcf72010-10-14 12:13:50 -07005899 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07005900 }
5901
Jeff Brown7fbdc842010-06-17 20:52:56 -07005902 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005903 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005904 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005905 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005906 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005907 continue;
5908 }
5909
Jeff Brown349703e2010-06-22 01:27:15 -07005910 final int flags = child.mAttrs.flags;
5911 final int type = child.mAttrs.type;
5912
5913 final boolean hasFocus = (child == mInputFocus);
5914 final boolean isVisible = child.isVisibleLw();
5915 final boolean hasWallpaper = (child == mWallpaperTarget)
5916 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005917
5918 // If there's a drag in progress and 'child' is a potential drop target,
5919 // make sure it's been told about the drag
5920 if (inDrag && isVisible) {
5921 mDragState.sendDragStartedIfNeededLw(child);
5922 }
5923
Jeff Brown349703e2010-06-22 01:27:15 -07005924 // Add a window to our list of input windows.
5925 final InputWindow inputWindow = mTempInputWindows.add();
Jeff Brown928e0542011-01-10 11:17:36 -08005926 inputWindow.inputWindowHandle = child.mInputWindowHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07005927 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005928 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005929 inputWindow.layoutParamsFlags = flags;
5930 inputWindow.layoutParamsType = type;
5931 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5932 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005933 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005934 inputWindow.hasFocus = hasFocus;
5935 inputWindow.hasWallpaper = hasWallpaper;
5936 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005937 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005938 inputWindow.ownerPid = child.mSession.mPid;
5939 inputWindow.ownerUid = child.mSession.mUid;
5940
5941 final Rect frame = child.mFrame;
5942 inputWindow.frameLeft = frame.left;
5943 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005944 inputWindow.frameRight = frame.right;
5945 inputWindow.frameBottom = frame.bottom;
5946
5947 final Rect visibleFrame = child.mVisibleFrame;
5948 inputWindow.visibleFrameLeft = visibleFrame.left;
5949 inputWindow.visibleFrameTop = visibleFrame.top;
5950 inputWindow.visibleFrameRight = visibleFrame.right;
5951 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005952
5953 switch (child.mTouchableInsets) {
5954 default:
5955 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5956 inputWindow.touchableAreaLeft = frame.left;
5957 inputWindow.touchableAreaTop = frame.top;
5958 inputWindow.touchableAreaRight = frame.right;
5959 inputWindow.touchableAreaBottom = frame.bottom;
5960 break;
5961
5962 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5963 Rect inset = child.mGivenContentInsets;
5964 inputWindow.touchableAreaLeft = frame.left + inset.left;
5965 inputWindow.touchableAreaTop = frame.top + inset.top;
5966 inputWindow.touchableAreaRight = frame.right - inset.right;
5967 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5968 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005969 }
Jeff Brown349703e2010-06-22 01:27:15 -07005970
5971 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5972 Rect inset = child.mGivenVisibleInsets;
5973 inputWindow.touchableAreaLeft = frame.left + inset.left;
5974 inputWindow.touchableAreaTop = frame.top + inset.top;
5975 inputWindow.touchableAreaRight = frame.right - inset.right;
5976 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005977 break;
5978 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005979 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005980 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005981
Jeff Brown349703e2010-06-22 01:27:15 -07005982 // Send windows to native code.
5983 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005984
Jeff Brown349703e2010-06-22 01:27:15 -07005985 // Clear the list in preparation for the next round.
5986 // Also avoids keeping InputChannel objects referenced unnecessarily.
5987 mTempInputWindows.clear();
5988 }
Jeff Brownb09abc12011-01-13 21:08:27 -08005989
5990 /* Notifies that the input device configuration has changed. */
5991 public void notifyConfigurationChanged() {
5992 sendNewConfiguration();
5993
5994 synchronized (mInputDevicesReadyMonitor) {
5995 if (!mInputDevicesReady) {
5996 mInputDevicesReady = true;
5997 mInputDevicesReadyMonitor.notifyAll();
5998 }
5999 }
6000 }
6001
6002 /* Waits until the built-in input devices have been configured. */
6003 public boolean waitForInputDevicesReady(long timeoutMillis) {
6004 synchronized (mInputDevicesReadyMonitor) {
6005 if (!mInputDevicesReady) {
6006 try {
6007 mInputDevicesReadyMonitor.wait(timeoutMillis);
6008 } catch (InterruptedException ex) {
6009 }
6010 }
6011 return mInputDevicesReady;
6012 }
6013 }
6014
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006015 /* Notifies that the lid switch changed state. */
6016 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
6017 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
6018 }
6019
Jeff Brown349703e2010-06-22 01:27:15 -07006020 /* Provides an opportunity for the window manager policy to intercept early key
6021 * processing as soon as the key has been read from the device. */
Jeff Brown1f245102010-11-18 20:53:46 -08006022 public int interceptKeyBeforeQueueing(
6023 KeyEvent event, int policyFlags, boolean isScreenOn) {
6024 return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07006025 }
6026
6027 /* Provides an opportunity for the window manager policy to process a key before
6028 * ordinary dispatch. */
Jeff Brown1f245102010-11-18 20:53:46 -08006029 public boolean interceptKeyBeforeDispatching(
Jeff Brown928e0542011-01-10 11:17:36 -08006030 InputWindowHandle focus, KeyEvent event, int policyFlags) {
Jeff Brown00ae87d2011-01-13 19:58:24 -08006031 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
Jeff Brown1f245102010-11-18 20:53:46 -08006032 return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07006033 }
6034
Jeff Brown3915bb82010-11-05 15:02:16 -07006035 /* Provides an opportunity for the window manager policy to process a key that
6036 * the application did not handle. */
Jeff Brown49ed71d2010-12-06 17:13:33 -08006037 public KeyEvent dispatchUnhandledKey(
Jeff Brown928e0542011-01-10 11:17:36 -08006038 InputWindowHandle focus, KeyEvent event, int policyFlags) {
Jeff Brown00ae87d2011-01-13 19:58:24 -08006039 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
Jeff Brown1f245102010-11-18 20:53:46 -08006040 return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07006041 }
6042
Jeff Brown349703e2010-06-22 01:27:15 -07006043 /* Called when the current input focus changes.
6044 * Layer assignment is assumed to be complete by the time this is called.
6045 */
6046 public void setInputFocusLw(WindowState newWindow) {
6047 if (DEBUG_INPUT) {
6048 Slog.d(TAG, "Input focus has changed to " + newWindow);
6049 }
6050
6051 if (newWindow != mInputFocus) {
6052 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07006053 // Displaying a window implicitly causes dispatching to be unpaused.
6054 // This is to protect against bugs if someone pauses dispatching but
6055 // forgets to resume.
6056 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006057 }
Jeff Brown349703e2010-06-22 01:27:15 -07006058
6059 mInputFocus = newWindow;
6060 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006061 }
6062 }
6063
Jeff Brown349703e2010-06-22 01:27:15 -07006064 public void setFocusedAppLw(AppWindowToken newApp) {
6065 // Focused app has changed.
6066 if (newApp == null) {
6067 mInputManager.setFocusedApplication(null);
6068 } else {
Jeff Brown928e0542011-01-10 11:17:36 -08006069 mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07006070 mTempInputApplication.name = newApp.toString();
6071 mTempInputApplication.dispatchingTimeoutNanos =
6072 newApp.inputDispatchingTimeoutNanos;
Jeff Brown928e0542011-01-10 11:17:36 -08006073
Jeff Brown349703e2010-06-22 01:27:15 -07006074 mInputManager.setFocusedApplication(mTempInputApplication);
Jeff Brown928e0542011-01-10 11:17:36 -08006075
6076 mTempInputApplication.recycle();
Jeff Brown349703e2010-06-22 01:27:15 -07006077 }
6078 }
6079
Jeff Brown349703e2010-06-22 01:27:15 -07006080 public void pauseDispatchingLw(WindowToken window) {
6081 if (! window.paused) {
6082 if (DEBUG_INPUT) {
6083 Slog.v(TAG, "Pausing WindowToken " + window);
6084 }
6085
6086 window.paused = true;
6087 updateInputWindowsLw();
6088 }
6089 }
6090
6091 public void resumeDispatchingLw(WindowToken window) {
6092 if (window.paused) {
6093 if (DEBUG_INPUT) {
6094 Slog.v(TAG, "Resuming WindowToken " + window);
6095 }
6096
6097 window.paused = false;
6098 updateInputWindowsLw();
6099 }
6100 }
6101
6102 public void freezeInputDispatchingLw() {
6103 if (! mInputDispatchFrozen) {
6104 if (DEBUG_INPUT) {
6105 Slog.v(TAG, "Freezing input dispatching");
6106 }
6107
6108 mInputDispatchFrozen = true;
6109 updateInputDispatchModeLw();
6110 }
6111 }
6112
6113 public void thawInputDispatchingLw() {
6114 if (mInputDispatchFrozen) {
6115 if (DEBUG_INPUT) {
6116 Slog.v(TAG, "Thawing input dispatching");
6117 }
6118
6119 mInputDispatchFrozen = false;
6120 updateInputDispatchModeLw();
6121 }
6122 }
6123
6124 public void setEventDispatchingLw(boolean enabled) {
6125 if (mInputDispatchEnabled != enabled) {
6126 if (DEBUG_INPUT) {
6127 Slog.v(TAG, "Setting event dispatching to " + enabled);
6128 }
6129
6130 mInputDispatchEnabled = enabled;
6131 updateInputDispatchModeLw();
6132 }
6133 }
6134
6135 private void updateInputDispatchModeLw() {
6136 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
6137 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 public void pauseKeyDispatching(IBinder _token) {
6141 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6142 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006143 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 }
6145
6146 synchronized (mWindowMap) {
6147 WindowToken token = mTokenMap.get(_token);
6148 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006149 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 }
6151 }
6152 }
6153
6154 public void resumeKeyDispatching(IBinder _token) {
6155 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6156 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006157 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006158 }
6159
6160 synchronized (mWindowMap) {
6161 WindowToken token = mTokenMap.get(_token);
6162 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006163 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 }
6165 }
6166 }
6167
6168 public void setEventDispatching(boolean enabled) {
6169 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6170 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006171 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006172 }
6173
6174 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006175 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006176 }
6177 }
Romain Guy06882f82009-06-10 13:36:04 -07006178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 /**
6180 * Injects a keystroke 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 keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006185 * {@link SystemClock#uptimeMillis()} as the timebase.)
6186 * @param sync If true, wait for the event to be completed before returning to the caller.
6187 * @return Returns true if event was dispatched, false if it was dropped for any reason
6188 */
6189 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6190 long downTime = ev.getDownTime();
6191 long eventTime = ev.getEventTime();
6192
6193 int action = ev.getAction();
6194 int code = ev.getKeyCode();
6195 int repeatCount = ev.getRepeatCount();
6196 int metaState = ev.getMetaState();
6197 int deviceId = ev.getDeviceId();
6198 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006199 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00006200 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006201
6202 if (source == InputDevice.SOURCE_UNKNOWN) {
6203 source = InputDevice.SOURCE_KEYBOARD;
6204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006205
6206 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6207 if (downTime == 0) downTime = eventTime;
6208
6209 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08006210 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006212 final int pid = Binder.getCallingPid();
6213 final int uid = Binder.getCallingUid();
6214 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006215
Jeff Brownbbda99d2010-07-28 15:48:59 -07006216 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6217 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6218 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6219 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006220
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006221 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006222 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006223 }
6224
6225 /**
6226 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006227 * Even when sync is false, this method may block while waiting for current
6228 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006229 *
6230 * @param ev A motion event describing the pointer (touch) action. (As noted in
6231 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 * {@link SystemClock#uptimeMillis()} as the timebase.)
6233 * @param sync If true, wait for the event to be completed before returning to the caller.
6234 * @return Returns true if event was dispatched, false if it was dropped for any reason
6235 */
6236 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006237 final int pid = Binder.getCallingPid();
6238 final int uid = Binder.getCallingUid();
6239 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006240
Jeff Brownc5ed5912010-07-14 18:48:53 -07006241 MotionEvent newEvent = MotionEvent.obtain(ev);
6242 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6243 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6244 }
6245
Jeff Brownbbda99d2010-07-28 15:48:59 -07006246 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6247 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6248 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6249 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006250
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006251 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006252 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 }
Romain Guy06882f82009-06-10 13:36:04 -07006254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 /**
6256 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006257 * Even when sync is false, this method may block while waiting for current
6258 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006259 *
6260 * @param ev A motion event describing the trackball action. (As noted in
6261 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006262 * {@link SystemClock#uptimeMillis()} as the timebase.)
6263 * @param sync If true, wait for the event to be completed before returning to the caller.
6264 * @return Returns true if event was dispatched, false if it was dropped for any reason
6265 */
6266 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006267 final int pid = Binder.getCallingPid();
6268 final int uid = Binder.getCallingUid();
6269 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006270
Jeff Brownc5ed5912010-07-14 18:48:53 -07006271 MotionEvent newEvent = MotionEvent.obtain(ev);
6272 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6273 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6274 }
6275
Jeff Brownbbda99d2010-07-28 15:48:59 -07006276 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6277 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6278 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6279 INJECTION_TIMEOUT_MILLIS);
6280
6281 Binder.restoreCallingIdentity(ident);
6282 return reportInjectionResult(result);
6283 }
6284
6285 /**
6286 * Inject an input event into the UI without waiting for dispatch to commence.
6287 * This variant is useful for fire-and-forget input event injection. It does not
6288 * block any longer than it takes to enqueue the input event.
6289 *
6290 * @param ev An input event. (Be sure to set the input source correctly.)
6291 * @return Returns true if event was dispatched, false if it was dropped for any reason
6292 */
6293 public boolean injectInputEventNoWait(InputEvent ev) {
6294 final int pid = Binder.getCallingPid();
6295 final int uid = Binder.getCallingUid();
6296 final long ident = Binder.clearCallingIdentity();
6297
6298 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6299 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6300 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006301
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006302 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006303 return reportInjectionResult(result);
6304 }
6305
6306 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006307 switch (result) {
6308 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6309 Slog.w(TAG, "Input event injection permission denied.");
6310 throw new SecurityException(
6311 "Injecting to another application requires INJECT_EVENTS permission");
6312 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006313 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006314 return true;
6315 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6316 Slog.w(TAG, "Input event injection timed out.");
6317 return false;
6318 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6319 default:
6320 Slog.w(TAG, "Input event injection failed.");
6321 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006323 }
Romain Guy06882f82009-06-10 13:36:04 -07006324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 private WindowState getFocusedWindow() {
6326 synchronized (mWindowMap) {
6327 return getFocusedWindowLocked();
6328 }
6329 }
6330
6331 private WindowState getFocusedWindowLocked() {
6332 return mCurrentFocus;
6333 }
Romain Guy06882f82009-06-10 13:36:04 -07006334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006336 if (!mInputMonitor.waitForInputDevicesReady(
6337 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6338 Slog.w(TAG, "Devices still not ready after waiting "
6339 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6340 + " milliseconds before attempting to detect safe mode.");
6341 }
6342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006343 mSafeMode = mPolicy.detectSafeMode();
6344 return mSafeMode;
6345 }
Romain Guy06882f82009-06-10 13:36:04 -07006346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006347 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006348 synchronized(mWindowMap) {
6349 if (mDisplay != null) {
6350 throw new IllegalStateException("Display already initialized");
6351 }
6352 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6353 mDisplay = wm.getDefaultDisplay();
6354 mInitialDisplayWidth = mDisplay.getWidth();
6355 mInitialDisplayHeight = mDisplay.getHeight();
Dianne Hackborn4c7cc342010-12-16 16:37:39 -08006356 mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
6357 Display.unmapDisplaySize(mInitialDisplayHeight));
Dianne Hackborn5132b372010-07-29 12:51:35 -07006358 }
6359
6360 try {
6361 mActivityManager.updateConfiguration(null);
6362 } catch (RemoteException e) {
6363 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006364
6365 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006366 }
6367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368 // -------------------------------------------------------------
6369 // Client Session State
6370 // -------------------------------------------------------------
6371
6372 private final class Session extends IWindowSession.Stub
6373 implements IBinder.DeathRecipient {
6374 final IInputMethodClient mClient;
6375 final IInputContext mInputContext;
6376 final int mUid;
6377 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006378 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006379 SurfaceSession mSurfaceSession;
6380 int mNumWindow = 0;
6381 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 public Session(IInputMethodClient client, IInputContext inputContext) {
6384 mClient = client;
6385 mInputContext = inputContext;
6386 mUid = Binder.getCallingUid();
6387 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006388 StringBuilder sb = new StringBuilder();
6389 sb.append("Session{");
6390 sb.append(Integer.toHexString(System.identityHashCode(this)));
6391 sb.append(" uid ");
6392 sb.append(mUid);
6393 sb.append("}");
6394 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 synchronized (mWindowMap) {
6397 if (mInputMethodManager == null && mHaveInputMethods) {
6398 IBinder b = ServiceManager.getService(
6399 Context.INPUT_METHOD_SERVICE);
6400 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6401 }
6402 }
6403 long ident = Binder.clearCallingIdentity();
6404 try {
6405 // Note: it is safe to call in to the input method manager
6406 // here because we are not holding our lock.
6407 if (mInputMethodManager != null) {
6408 mInputMethodManager.addClient(client, inputContext,
6409 mUid, mPid);
6410 } else {
6411 client.setUsingInputMethod(false);
6412 }
6413 client.asBinder().linkToDeath(this, 0);
6414 } catch (RemoteException e) {
6415 // The caller has died, so we can just forget about this.
6416 try {
6417 if (mInputMethodManager != null) {
6418 mInputMethodManager.removeClient(client);
6419 }
6420 } catch (RemoteException ee) {
6421 }
6422 } finally {
6423 Binder.restoreCallingIdentity(ident);
6424 }
6425 }
Romain Guy06882f82009-06-10 13:36:04 -07006426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006427 @Override
6428 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6429 throws RemoteException {
6430 try {
6431 return super.onTransact(code, data, reply, flags);
6432 } catch (RuntimeException e) {
6433 // Log all 'real' exceptions thrown to the caller
6434 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006435 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006436 }
6437 throw e;
6438 }
6439 }
6440
6441 public void binderDied() {
6442 // Note: it is safe to call in to the input method manager
6443 // here because we are not holding our lock.
6444 try {
6445 if (mInputMethodManager != null) {
6446 mInputMethodManager.removeClient(mClient);
6447 }
6448 } catch (RemoteException e) {
6449 }
6450 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006451 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 mClientDead = true;
6453 killSessionLocked();
6454 }
6455 }
6456
6457 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006458 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6459 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6460 outInputChannel);
6461 }
6462
6463 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006464 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006465 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006466 }
Romain Guy06882f82009-06-10 13:36:04 -07006467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006468 public void remove(IWindow window) {
6469 removeWindow(this, window);
6470 }
Romain Guy06882f82009-06-10 13:36:04 -07006471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006472 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6473 int requestedWidth, int requestedHeight, int viewFlags,
6474 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006475 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006476 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6477 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006479 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006480 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6481 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006482 }
Romain Guy06882f82009-06-10 13:36:04 -07006483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 public void setTransparentRegion(IWindow window, Region region) {
6485 setTransparentRegionWindow(this, window, region);
6486 }
Romain Guy06882f82009-06-10 13:36:04 -07006487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 public void setInsets(IWindow window, int touchableInsets,
6489 Rect contentInsets, Rect visibleInsets) {
6490 setInsetsWindow(this, window, touchableInsets, contentInsets,
6491 visibleInsets);
6492 }
Romain Guy06882f82009-06-10 13:36:04 -07006493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006494 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6495 getWindowDisplayFrame(this, window, outDisplayFrame);
6496 }
Romain Guy06882f82009-06-10 13:36:04 -07006497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006498 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006499 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 TAG, "IWindow finishDrawing called for " + window);
6501 finishDrawingWindow(this, window);
6502 }
6503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006504 public void setInTouchMode(boolean mode) {
6505 synchronized(mWindowMap) {
6506 mInTouchMode = mode;
6507 }
6508 }
6509
6510 public boolean getInTouchMode() {
6511 synchronized(mWindowMap) {
6512 return mInTouchMode;
6513 }
6514 }
6515
6516 public boolean performHapticFeedback(IWindow window, int effectId,
6517 boolean always) {
6518 synchronized(mWindowMap) {
6519 long ident = Binder.clearCallingIdentity();
6520 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006521 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006522 windowForClientLocked(this, window, true),
6523 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006524 } finally {
6525 Binder.restoreCallingIdentity(ident);
6526 }
6527 }
6528 }
Romain Guy06882f82009-06-10 13:36:04 -07006529
Christopher Tatea53146c2010-09-07 11:57:52 -07006530 /* Drag/drop */
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006531 public IBinder prepareDrag(IWindow window, int flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006532 int width, int height, Surface outSurface) {
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006533 return prepareDragSurface(window, mSurfaceSession, flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006534 width, height, outSurface);
6535 }
6536
6537 public boolean performDrag(IWindow window, IBinder dragToken,
6538 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6539 ClipData data) {
6540 if (DEBUG_DRAG) {
6541 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6542 }
6543
6544 synchronized (mWindowMap) {
6545 if (mDragState == null) {
6546 Slog.w(TAG, "No drag prepared");
6547 throw new IllegalStateException("performDrag() without prepareDrag()");
6548 }
6549
6550 if (dragToken != mDragState.mToken) {
6551 Slog.w(TAG, "Performing mismatched drag");
6552 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6553 }
6554
6555 WindowState callingWin = windowForClientLocked(null, window, false);
6556 if (callingWin == null) {
6557 Slog.w(TAG, "Bad requesting window " + window);
6558 return false; // !!! TODO: throw here?
6559 }
6560
6561 // !!! TODO: if input is not still focused on the initiating window, fail
6562 // the drag initiation (e.g. an alarm window popped up just as the application
6563 // called performDrag()
6564
6565 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6566
Christopher Tate2c095f32010-10-04 14:13:40 -07006567 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6568 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006569
Chris Tateb478f462010-10-15 16:02:26 -07006570 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6571 // the actual drag event dispatch stuff in the dragstate
6572
Christopher Tatea53146c2010-09-07 11:57:52 -07006573 mDragState.register();
6574 mInputMonitor.updateInputWindowsLw();
Chris Tateef70a072010-10-22 19:10:34 -07006575 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6576 mDragState.mServerChannel)) {
6577 Slog.e(TAG, "Unable to transfer touch focus");
6578 mDragState.unregister();
6579 mDragState = null;
6580 mInputMonitor.updateInputWindowsLw();
6581 return false;
6582 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006583
6584 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006585 mDragState.mCurrentX = touchX;
6586 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006587 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006588
6589 // remember the thumb offsets for later
6590 mDragState.mThumbOffsetX = thumbCenterX;
6591 mDragState.mThumbOffsetY = thumbCenterY;
6592
6593 // Make the surface visible at the proper location
6594 final Surface surface = mDragState.mSurface;
Chris Tateb478f462010-10-15 16:02:26 -07006595 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006596 try {
6597 surface.setPosition((int)(touchX - thumbCenterX),
6598 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006599 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006600 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006601 surface.show();
6602 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006603 Surface.closeTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006604 }
6605 }
6606
6607 return true; // success!
6608 }
6609
Chris Tated4533f142010-10-19 15:15:08 -07006610 public void reportDropResult(IWindow window, boolean consumed) {
6611 IBinder token = window.asBinder();
6612 if (DEBUG_DRAG) {
6613 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6614 }
6615
6616 synchronized (mWindowMap) {
Christopher Tateccd24de2011-01-12 15:02:55 -08006617 long ident = Binder.clearCallingIdentity();
6618 try {
6619 if (mDragState.mToken != token) {
6620 Slog.w(TAG, "Invalid drop-result claim by " + window);
6621 throw new IllegalStateException("reportDropResult() by non-recipient");
6622 }
6623
6624 // The right window has responded, even if it's no longer around,
6625 // so be sure to halt the timeout even if the later WindowState
6626 // lookup fails.
6627 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6628 WindowState callingWin = windowForClientLocked(null, window, false);
6629 if (callingWin == null) {
6630 Slog.w(TAG, "Bad result-reporting window " + window);
6631 return; // !!! TODO: throw here?
6632 }
6633
6634 mDragState.mDragResult = consumed;
6635 mDragState.endDragLw();
6636 } finally {
6637 Binder.restoreCallingIdentity(ident);
Chris Tated4533f142010-10-19 15:15:08 -07006638 }
Chris Tated4533f142010-10-19 15:15:08 -07006639 }
6640 }
6641
Christopher Tatea53146c2010-09-07 11:57:52 -07006642 public void dragRecipientEntered(IWindow window) {
6643 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006644 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006645 }
6646 }
6647
6648 public void dragRecipientExited(IWindow window) {
6649 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006650 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006651 }
6652 }
6653
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006654 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006655 synchronized(mWindowMap) {
6656 long ident = Binder.clearCallingIdentity();
6657 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006658 setWindowWallpaperPositionLocked(
6659 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006660 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006661 } finally {
6662 Binder.restoreCallingIdentity(ident);
6663 }
6664 }
6665 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006666
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006667 public void wallpaperOffsetsComplete(IBinder window) {
6668 WindowManagerService.this.wallpaperOffsetsComplete(window);
6669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006670
Dianne Hackborn75804932009-10-20 20:15:20 -07006671 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6672 int z, Bundle extras, boolean sync) {
6673 synchronized(mWindowMap) {
6674 long ident = Binder.clearCallingIdentity();
6675 try {
6676 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006677 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006678 action, x, y, z, extras, sync);
6679 } finally {
6680 Binder.restoreCallingIdentity(ident);
6681 }
6682 }
6683 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006684
Dianne Hackborn75804932009-10-20 20:15:20 -07006685 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6686 WindowManagerService.this.wallpaperCommandComplete(window, result);
6687 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006689 void windowAddedLocked() {
6690 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006691 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 TAG, "First window added to " + this + ", creating SurfaceSession");
6693 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006694 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006695 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006696 mSessions.add(this);
6697 }
6698 mNumWindow++;
6699 }
6700
6701 void windowRemovedLocked() {
6702 mNumWindow--;
6703 killSessionLocked();
6704 }
Romain Guy06882f82009-06-10 13:36:04 -07006705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006706 void killSessionLocked() {
6707 if (mNumWindow <= 0 && mClientDead) {
6708 mSessions.remove(this);
6709 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006710 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006711 TAG, "Last window removed from " + this
6712 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006713 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006714 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 try {
6716 mSurfaceSession.kill();
6717 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006718 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 + mSurfaceSession + " in session " + this
6720 + ": " + e.toString());
6721 }
6722 mSurfaceSession = null;
6723 }
6724 }
6725 }
Romain Guy06882f82009-06-10 13:36:04 -07006726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006728 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6729 pw.print(" mClientDead="); pw.print(mClientDead);
6730 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 }
6732
6733 @Override
6734 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006735 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 }
6737 }
6738
6739 // -------------------------------------------------------------
6740 // Client Window State
6741 // -------------------------------------------------------------
6742
6743 private final class WindowState implements WindowManagerPolicy.WindowState {
6744 final Session mSession;
6745 final IWindow mClient;
6746 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006747 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006748 AppWindowToken mAppToken;
6749 AppWindowToken mTargetAppToken;
6750 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6751 final DeathRecipient mDeathRecipient;
6752 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006753 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 final int mBaseLayer;
6755 final int mSubLayer;
6756 final boolean mLayoutAttached;
6757 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006758 final boolean mIsWallpaper;
6759 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006760 int mViewVisibility;
6761 boolean mPolicyVisibility = true;
6762 boolean mPolicyVisibilityAfterAnim = true;
6763 boolean mAppFreezing;
6764 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006765 boolean mReportDestroySurface;
6766 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006767 boolean mAttachedHidden; // is our parent window hidden?
6768 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006769 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006770 int mRequestedWidth;
6771 int mRequestedHeight;
6772 int mLastRequestedWidth;
6773 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774 int mLayer;
6775 int mAnimLayer;
6776 int mLastLayer;
6777 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006778 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006779 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006781 int mLayoutSeq = -1;
6782
6783 Configuration mConfiguration = null;
6784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 // Actual frame shown on-screen (may be modified by animation)
6786 final Rect mShownFrame = new Rect();
6787 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006790 * Set when we have changed the size of the surface, to know that
6791 * we must tell them application to resize (and thus redraw itself).
6792 */
6793 boolean mSurfaceResized;
6794
6795 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 * Insets that determine the actually visible area
6797 */
6798 final Rect mVisibleInsets = new Rect();
6799 final Rect mLastVisibleInsets = new Rect();
6800 boolean mVisibleInsetsChanged;
6801
6802 /**
6803 * Insets that are covered by system windows
6804 */
6805 final Rect mContentInsets = new Rect();
6806 final Rect mLastContentInsets = new Rect();
6807 boolean mContentInsetsChanged;
6808
6809 /**
6810 * Set to true if we are waiting for this window to receive its
6811 * given internal insets before laying out other windows based on it.
6812 */
6813 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 /**
6816 * These are the content insets that were given during layout for
6817 * this window, to be applied to windows behind it.
6818 */
6819 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821 /**
6822 * These are the visible insets that were given during layout for
6823 * this window, to be applied to windows behind it.
6824 */
6825 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006827 /**
6828 * Flag indicating whether the touchable region should be adjusted by
6829 * the visible insets; if false the area outside the visible insets is
6830 * NOT touchable, so we must use those to adjust the frame during hit
6831 * tests.
6832 */
6833 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 // Current transformation being applied.
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08006836 boolean mHaveMatrix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6838 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6839 float mHScale=1, mVScale=1;
6840 float mLastHScale=1, mLastVScale=1;
6841 final Matrix mTmpMatrix = new Matrix();
6842
6843 // "Real" frame that the application sees.
6844 final Rect mFrame = new Rect();
6845 final Rect mLastFrame = new Rect();
6846
6847 final Rect mContainingFrame = new Rect();
6848 final Rect mDisplayFrame = new Rect();
6849 final Rect mContentFrame = new Rect();
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006850 final Rect mParentFrame = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 final Rect mVisibleFrame = new Rect();
6852
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006853 boolean mContentChanged;
6854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 float mShownAlpha = 1;
6856 float mAlpha = 1;
6857 float mLastAlpha = 1;
6858
6859 // Set to true if, when the window gets displayed, it should perform
6860 // an enter animation.
6861 boolean mEnterAnimationPending;
6862
6863 // Currently running animation.
6864 boolean mAnimating;
6865 boolean mLocalAnimating;
6866 Animation mAnimation;
6867 boolean mAnimationIsEntrance;
6868 boolean mHasTransformation;
6869 boolean mHasLocalTransformation;
6870 final Transformation mTransformation = new Transformation();
6871
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006872 // If a window showing a wallpaper: the requested offset for the
6873 // wallpaper; if a wallpaper window: the currently applied offset.
6874 float mWallpaperX = -1;
6875 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006876
6877 // If a window showing a wallpaper: what fraction of the offset
6878 // range corresponds to a full virtual screen.
6879 float mWallpaperXStep = -1;
6880 float mWallpaperYStep = -1;
6881
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006882 // Wallpaper windows: pixels offset based on above variables.
6883 int mXOffset;
6884 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 // This is set after IWindowSession.relayout() has been called at
6887 // least once for the window. It allows us to detect the situation
6888 // where we don't yet have a surface, but should have one soon, so
6889 // we can give the window focus before waiting for the relayout.
6890 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006892 // This is set after the Surface has been created but before the
6893 // window has been drawn. During this time the surface is hidden.
6894 boolean mDrawPending;
6895
6896 // This is set after the window has finished drawing for the first
6897 // time but before its surface is shown. The surface will be
6898 // displayed when the next layout is run.
6899 boolean mCommitDrawPending;
6900
6901 // This is set during the time after the window's drawing has been
6902 // committed, and before its surface is actually shown. It is used
6903 // to delay showing the surface until all windows in a token are ready
6904 // to be shown.
6905 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006907 // Set when the window has been shown in the screen the first time.
6908 boolean mHasDrawn;
6909
6910 // Currently running an exit animation?
6911 boolean mExiting;
6912
6913 // Currently on the mDestroySurface list?
6914 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 // Completely remove from window manager after exit animation?
6917 boolean mRemoveOnExit;
6918
6919 // Set when the orientation is changing and this window has not yet
6920 // been updated for the new orientation.
6921 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006923 // Is this window now (or just being) removed?
6924 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006925
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006926 // Temp for keeping track of windows that have been removed when
6927 // rebuilding window list.
6928 boolean mRebuilding;
6929
Dianne Hackborn16064f92010-03-25 00:47:24 -07006930 // For debugging, this is the last information given to the surface flinger.
6931 boolean mSurfaceShown;
6932 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6933 int mSurfaceLayer;
6934 float mSurfaceAlpha;
6935
Jeff Brown928e0542011-01-10 11:17:36 -08006936 // Input channel and input window handle used by the input dispatcher.
6937 InputWindowHandle mInputWindowHandle;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006938 InputChannel mInputChannel;
6939
Mattias Petersson1622eee2010-12-21 10:15:11 +01006940 // Used to improve performance of toString()
6941 String mStringNameCache;
6942 CharSequence mLastTitle;
6943 boolean mWasPaused;
6944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 WindowState(Session s, IWindow c, WindowToken token,
6946 WindowState attachedWindow, WindowManager.LayoutParams a,
6947 int viewVisibility) {
6948 mSession = s;
6949 mClient = c;
6950 mToken = token;
6951 mAttrs.copyFrom(a);
6952 mViewVisibility = viewVisibility;
6953 DeathRecipient deathRecipient = new DeathRecipient();
6954 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006955 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 TAG, "Window " + this + " client=" + c.asBinder()
6957 + " token=" + token + " (" + mAttrs.token + ")");
6958 try {
6959 c.asBinder().linkToDeath(deathRecipient, 0);
6960 } catch (RemoteException e) {
6961 mDeathRecipient = null;
6962 mAttachedWindow = null;
6963 mLayoutAttached = false;
6964 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006965 mIsWallpaper = false;
6966 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006967 mBaseLayer = 0;
6968 mSubLayer = 0;
6969 return;
6970 }
6971 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6974 mAttrs.type <= LAST_SUB_WINDOW)) {
6975 // The multiplier here is to reserve space for multiple
6976 // windows in the same type layer.
6977 mBaseLayer = mPolicy.windowTypeToLayerLw(
6978 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6979 + TYPE_LAYER_OFFSET;
6980 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6981 mAttachedWindow = attachedWindow;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006982 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006983 mAttachedWindow.mChildWindows.add(this);
6984 mLayoutAttached = mAttrs.type !=
6985 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6986 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6987 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006988 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6989 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 } else {
6991 // The multiplier here is to reserve space for multiple
6992 // windows in the same type layer.
6993 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6994 * TYPE_LAYER_MULTIPLIER
6995 + TYPE_LAYER_OFFSET;
6996 mSubLayer = 0;
6997 mAttachedWindow = null;
6998 mLayoutAttached = false;
6999 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7000 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007001 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7002 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007003 }
7004
7005 WindowState appWin = this;
7006 while (appWin.mAttachedWindow != null) {
7007 appWin = mAttachedWindow;
7008 }
7009 WindowToken appToken = appWin.mToken;
7010 while (appToken.appWindowToken == null) {
7011 WindowToken parent = mTokenMap.get(appToken.token);
7012 if (parent == null || appToken == parent) {
7013 break;
7014 }
7015 appToken = parent;
7016 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007017 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 mAppToken = appToken.appWindowToken;
7019
7020 mSurface = null;
7021 mRequestedWidth = 0;
7022 mRequestedHeight = 0;
7023 mLastRequestedWidth = 0;
7024 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007025 mXOffset = 0;
7026 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 mLayer = 0;
7028 mAnimLayer = 0;
7029 mLastLayer = 0;
Jeff Brown928e0542011-01-10 11:17:36 -08007030 mInputWindowHandle = new InputWindowHandle(
7031 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007032 }
7033
7034 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007035 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007036 TAG, "Attaching " + this + " token=" + mToken
7037 + ", list=" + mToken.windows);
7038 mSession.windowAddedLocked();
7039 }
7040
7041 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7042 mHaveFrame = true;
7043
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007044 final Rect container = mContainingFrame;
7045 container.set(pf);
7046
7047 final Rect display = mDisplayFrame;
7048 display.set(df);
7049
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007050 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007051 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007052 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7053 display.intersect(mCompatibleScreenFrame);
7054 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007055 }
7056
7057 final int pw = container.right - container.left;
7058 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059
7060 int w,h;
7061 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7062 w = mAttrs.width < 0 ? pw : mAttrs.width;
7063 h = mAttrs.height< 0 ? ph : mAttrs.height;
7064 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007065 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7066 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 }
Romain Guy06882f82009-06-10 13:36:04 -07007068
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007069 if (!mParentFrame.equals(pf)) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007070 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
7071 // + " to " + pf);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007072 mParentFrame.set(pf);
7073 mContentChanged = true;
7074 }
7075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 final Rect content = mContentFrame;
7077 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 final Rect visible = mVisibleFrame;
7080 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007082 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007083 final int fw = frame.width();
7084 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007086 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7087 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7088
7089 Gravity.apply(mAttrs.gravity, w, h, container,
7090 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7091 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7092
7093 //System.out.println("Out: " + mFrame);
7094
7095 // Now make sure the window fits in the overall display.
7096 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 // Make sure the content and visible frames are inside of the
7099 // final window frame.
7100 if (content.left < frame.left) content.left = frame.left;
7101 if (content.top < frame.top) content.top = frame.top;
7102 if (content.right > frame.right) content.right = frame.right;
7103 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7104 if (visible.left < frame.left) visible.left = frame.left;
7105 if (visible.top < frame.top) visible.top = frame.top;
7106 if (visible.right > frame.right) visible.right = frame.right;
7107 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007109 final Rect contentInsets = mContentInsets;
7110 contentInsets.left = content.left-frame.left;
7111 contentInsets.top = content.top-frame.top;
7112 contentInsets.right = frame.right-content.right;
7113 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 final Rect visibleInsets = mVisibleInsets;
7116 visibleInsets.left = visible.left-frame.left;
7117 visibleInsets.top = visible.top-frame.top;
7118 visibleInsets.right = frame.right-visible.right;
7119 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007120
Dianne Hackborn284ac932009-08-28 10:34:25 -07007121 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7122 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007123 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007124 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007126 if (localLOGV) {
7127 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7128 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007129 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007130 + mRequestedWidth + ", mRequestedheight="
7131 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7132 + "): frame=" + mFrame.toShortString()
7133 + " ci=" + contentInsets.toShortString()
7134 + " vi=" + visibleInsets.toShortString());
7135 //}
7136 }
7137 }
Romain Guy06882f82009-06-10 13:36:04 -07007138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007139 public Rect getFrameLw() {
7140 return mFrame;
7141 }
7142
7143 public Rect getShownFrameLw() {
7144 return mShownFrame;
7145 }
7146
7147 public Rect getDisplayFrameLw() {
7148 return mDisplayFrame;
7149 }
7150
7151 public Rect getContentFrameLw() {
7152 return mContentFrame;
7153 }
7154
7155 public Rect getVisibleFrameLw() {
7156 return mVisibleFrame;
7157 }
7158
7159 public boolean getGivenInsetsPendingLw() {
7160 return mGivenInsetsPending;
7161 }
7162
7163 public Rect getGivenContentInsetsLw() {
7164 return mGivenContentInsets;
7165 }
Romain Guy06882f82009-06-10 13:36:04 -07007166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 public Rect getGivenVisibleInsetsLw() {
7168 return mGivenVisibleInsets;
7169 }
Romain Guy06882f82009-06-10 13:36:04 -07007170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 public WindowManager.LayoutParams getAttrs() {
7172 return mAttrs;
7173 }
7174
7175 public int getSurfaceLayer() {
7176 return mLayer;
7177 }
Romain Guy06882f82009-06-10 13:36:04 -07007178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007179 public IApplicationToken getAppToken() {
7180 return mAppToken != null ? mAppToken.appToken : null;
7181 }
Jeff Brown349703e2010-06-22 01:27:15 -07007182
7183 public long getInputDispatchingTimeoutNanos() {
7184 return mAppToken != null
7185 ? mAppToken.inputDispatchingTimeoutNanos
7186 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188
7189 public boolean hasAppShownWindows() {
7190 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7191 }
7192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007194 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007195 TAG, "Setting animation in " + this + ": " + anim);
7196 mAnimating = false;
7197 mLocalAnimating = false;
7198 mAnimation = anim;
7199 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7200 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7201 }
7202
7203 public void clearAnimation() {
7204 if (mAnimation != null) {
7205 mAnimating = true;
7206 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007207 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007208 mAnimation = null;
7209 }
7210 }
Romain Guy06882f82009-06-10 13:36:04 -07007211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 Surface createSurfaceLocked() {
7213 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007214 mReportDestroySurface = false;
7215 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 mDrawPending = true;
7217 mCommitDrawPending = false;
7218 mReadyToShow = false;
7219 if (mAppToken != null) {
7220 mAppToken.allDrawn = false;
7221 }
7222
7223 int flags = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007224
7225 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7226 flags |= Surface.SECURE;
7227 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007228 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007229 TAG, "Creating surface in session "
7230 + mSession.mSurfaceSession + " window " + this
7231 + " w=" + mFrame.width()
7232 + " h=" + mFrame.height() + " format="
7233 + mAttrs.format + " flags=" + flags);
7234
7235 int w = mFrame.width();
7236 int h = mFrame.height();
7237 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7238 // for a scaled surface, we always want the requested
7239 // size.
7240 w = mRequestedWidth;
7241 h = mRequestedHeight;
7242 }
7243
Romain Guy9825ec62009-10-01 00:58:09 -07007244 // Something is wrong and SurfaceFlinger will not like this,
7245 // try to revert to sane values
7246 if (w <= 0) w = 1;
7247 if (h <= 0) h = 1;
7248
Dianne Hackborn16064f92010-03-25 00:47:24 -07007249 mSurfaceShown = false;
7250 mSurfaceLayer = 0;
7251 mSurfaceAlpha = 1;
7252 mSurfaceX = 0;
7253 mSurfaceY = 0;
7254 mSurfaceW = w;
7255 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 try {
Romain Guyd10cd572010-10-10 13:33:22 -07007257 final boolean isHwAccelerated = (mAttrs.flags &
7258 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
7259 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
7260 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
7261 flags |= Surface.OPAQUE;
7262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007263 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007264 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007265 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07007266 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007267 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007268 + mSurface + " IN SESSION "
7269 + mSession.mSurfaceSession
7270 + ": pid=" + mSession.mPid + " format="
7271 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007272 + Integer.toHexString(flags)
7273 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007275 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 reclaimSomeSurfaceMemoryLocked(this, "create");
7277 return null;
7278 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007279 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007280 return null;
7281 }
Romain Guy06882f82009-06-10 13:36:04 -07007282
Joe Onorato8a9b2202010-02-26 18:56:32 -08007283 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007284 TAG, "Got surface: " + mSurface
7285 + ", set left=" + mFrame.left + " top=" + mFrame.top
7286 + ", animLayer=" + mAnimLayer);
7287 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007288 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007289 if (SHOW_TRANSACTIONS) logSurface(this,
7290 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7291 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7292 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007293 }
7294 Surface.openTransaction();
7295 try {
7296 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007297 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007298 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007299 mSurface.setPosition(mSurfaceX, mSurfaceY);
7300 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007301 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007302 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007303 mSurface.hide();
7304 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007305 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007306 mSurface.setFlags(Surface.SURFACE_DITHER,
7307 Surface.SURFACE_DITHER);
7308 }
7309 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007310 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7312 }
7313 mLastHidden = true;
7314 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007315 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007316 Surface.closeTransaction();
7317 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007318 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 TAG, "Created surface " + this);
7320 }
7321 return mSurface;
7322 }
Romain Guy06882f82009-06-10 13:36:04 -07007323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007324 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007325 if (mAppToken != null && this == mAppToken.startingWindow) {
7326 mAppToken.startingDisplayed = false;
7327 }
Romain Guy06882f82009-06-10 13:36:04 -07007328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007330 mDrawPending = false;
7331 mCommitDrawPending = false;
7332 mReadyToShow = false;
7333
7334 int i = mChildWindows.size();
7335 while (i > 0) {
7336 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007337 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007338 c.mAttachedHidden = true;
7339 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007340
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007341 if (mReportDestroySurface) {
7342 mReportDestroySurface = false;
7343 mSurfacePendingDestroy = true;
7344 try {
7345 mClient.dispatchGetNewSurface();
7346 // We'll really destroy on the next time around.
7347 return;
7348 } catch (RemoteException e) {
7349 }
7350 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007352 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007353 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007354 RuntimeException e = null;
7355 if (!HIDE_STACK_CRAWLS) {
7356 e = new RuntimeException();
7357 e.fillInStackTrace();
7358 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007359 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007360 + mSurface + ", session " + mSession, e);
7361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007363 RuntimeException e = null;
7364 if (!HIDE_STACK_CRAWLS) {
7365 e = new RuntimeException();
7366 e.fillInStackTrace();
7367 }
7368 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007370 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007372 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007373 + " surface " + mSurface + " session " + mSession
7374 + ": " + e.toString());
7375 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007376
Dianne Hackborn16064f92010-03-25 00:47:24 -07007377 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 }
7380 }
7381
7382 boolean finishDrawingLocked() {
7383 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007384 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 TAG, "finishDrawingLocked: " + mSurface);
7386 mCommitDrawPending = true;
7387 mDrawPending = false;
7388 return true;
7389 }
7390 return false;
7391 }
7392
7393 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007394 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007395 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007396 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007397 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007398 }
7399 mCommitDrawPending = false;
7400 mReadyToShow = true;
7401 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7402 final AppWindowToken atoken = mAppToken;
7403 if (atoken == null || atoken.allDrawn || starting) {
7404 performShowLocked();
7405 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007406 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007407 }
7408
7409 // This must be called while inside a transaction.
7410 boolean performShowLocked() {
7411 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007412 RuntimeException e = null;
7413 if (!HIDE_STACK_CRAWLS) {
7414 e = new RuntimeException();
7415 e.fillInStackTrace();
7416 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007417 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7419 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7420 }
7421 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007422 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7423 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007424 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 + " during animation: policyVis=" + mPolicyVisibility
7426 + " attHidden=" + mAttachedHidden
7427 + " tok.hiddenRequested="
7428 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007429 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007430 + (mAppToken != null ? mAppToken.hidden : false)
7431 + " animating=" + mAnimating
7432 + " tok animating="
7433 + (mAppToken != null ? mAppToken.animating : false));
7434 if (!showSurfaceRobustlyLocked(this)) {
7435 return false;
7436 }
7437 mLastAlpha = -1;
7438 mHasDrawn = true;
7439 mLastHidden = false;
7440 mReadyToShow = false;
7441 enableScreenIfNeededLocked();
7442
7443 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007445 int i = mChildWindows.size();
7446 while (i > 0) {
7447 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007448 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007449 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007451 if (c.mSurface != null) {
7452 c.performShowLocked();
7453 // It hadn't been shown, which means layout not
7454 // performed on it, so now we want to make sure to
7455 // do a layout. If called from within the transaction
7456 // loop, this will cause it to restart with a new
7457 // layout.
7458 mLayoutNeeded = true;
7459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 }
7461 }
Romain Guy06882f82009-06-10 13:36:04 -07007462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007463 if (mAttrs.type != TYPE_APPLICATION_STARTING
7464 && mAppToken != null) {
7465 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007466
Dianne Hackborn248b1882009-09-16 16:46:44 -07007467 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007468 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007469 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007471 // If this initial window is animating, stop it -- we
7472 // will do an animation to reveal it from behind the
7473 // starting window, so there is no need for it to also
7474 // be doing its own stuff.
7475 if (mAnimation != null) {
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007476 mAnimation.cancel();
Dianne Hackborn248b1882009-09-16 16:46:44 -07007477 mAnimation = null;
7478 // Make sure we clean up the animation.
7479 mAnimating = true;
7480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 mFinishedStarting.add(mAppToken);
7482 mH.sendEmptyMessage(H.FINISHED_STARTING);
7483 }
7484 mAppToken.updateReportedVisibilityLocked();
7485 }
7486 }
7487 return true;
7488 }
Romain Guy06882f82009-06-10 13:36:04 -07007489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007490 // This must be called while inside a transaction. Returns true if
7491 // there is more animation to run.
7492 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007493 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7497 mHasTransformation = true;
7498 mHasLocalTransformation = true;
7499 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007500 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007501 TAG, "Starting animation in " + this +
7502 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7503 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7504 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7505 mAnimation.setStartTime(currentTime);
7506 mLocalAnimating = true;
7507 mAnimating = true;
7508 }
7509 mTransformation.clear();
7510 final boolean more = mAnimation.getTransformation(
7511 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007512 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 TAG, "Stepped animation in " + this +
7514 ": more=" + more + ", xform=" + mTransformation);
7515 if (more) {
7516 // we're not done!
7517 return true;
7518 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007519 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007520 TAG, "Finished animation in " + this +
7521 " @ " + currentTime);
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007522
7523 if (mAnimation != null) {
7524 mAnimation.cancel();
7525 mAnimation = null;
7526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 //WindowManagerService.this.dump();
7528 }
7529 mHasLocalTransformation = false;
7530 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007531 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007532 // When our app token is animating, we kind-of pretend like
7533 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7534 // part of this check means that we will only do this if
7535 // our window is not currently exiting, or it is not
7536 // locally animating itself. The idea being that one that
7537 // is exiting and doing a local animation should be removed
7538 // once that animation is done.
7539 mAnimating = true;
7540 mHasTransformation = true;
7541 mTransformation.clear();
7542 return false;
7543 } else if (mHasTransformation) {
7544 // Little trick to get through the path below to act like
7545 // we have finished an animation.
7546 mAnimating = true;
7547 } else if (isAnimating()) {
7548 mAnimating = true;
7549 }
7550 } else if (mAnimation != null) {
7551 // If the display is frozen, and there is a pending animation,
7552 // clear it and make sure we run the cleanup code.
7553 mAnimating = true;
7554 mLocalAnimating = true;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007555 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007556 mAnimation = null;
7557 }
Romain Guy06882f82009-06-10 13:36:04 -07007558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 if (!mAnimating && !mLocalAnimating) {
7560 return false;
7561 }
7562
Joe Onorato8a9b2202010-02-26 18:56:32 -08007563 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007564 TAG, "Animation done in " + this + ": exiting=" + mExiting
7565 + ", reportedVisible="
7566 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007568 mAnimating = false;
7569 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007570 if (mAnimation != null) {
7571 mAnimation.cancel();
7572 mAnimation = null;
7573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007574 mAnimLayer = mLayer;
7575 if (mIsImWindow) {
7576 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007577 } else if (mIsWallpaper) {
7578 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007579 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007580 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007581 + " anim layer: " + mAnimLayer);
7582 mHasTransformation = false;
7583 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007584 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7585 if (DEBUG_VISIBILITY) {
7586 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7587 + mPolicyVisibilityAfterAnim);
7588 }
7589 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7590 if (!mPolicyVisibility) {
7591 if (mCurrentFocus == this) {
7592 mFocusMayChange = true;
7593 }
7594 // Window is no longer visible -- make sure if we were waiting
7595 // for it to be displayed before enabling the display, that
7596 // we allow the display to be enabled now.
7597 enableScreenIfNeededLocked();
7598 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600 mTransformation.clear();
7601 if (mHasDrawn
7602 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7603 && mAppToken != null
7604 && mAppToken.firstWindowDrawn
7605 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007606 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007607 + mToken + ": first real window done animating");
7608 mFinishedStarting.add(mAppToken);
7609 mH.sendEmptyMessage(H.FINISHED_STARTING);
7610 }
Romain Guy06882f82009-06-10 13:36:04 -07007611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007612 finishExit();
7613
7614 if (mAppToken != null) {
7615 mAppToken.updateReportedVisibilityLocked();
7616 }
7617
7618 return false;
7619 }
7620
7621 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007622 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007623 TAG, "finishExit in " + this
7624 + ": exiting=" + mExiting
7625 + " remove=" + mRemoveOnExit
7626 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 final int N = mChildWindows.size();
7629 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007630 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 }
Romain Guy06882f82009-06-10 13:36:04 -07007632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 if (!mExiting) {
7634 return;
7635 }
Romain Guy06882f82009-06-10 13:36:04 -07007636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 if (isWindowAnimating()) {
7638 return;
7639 }
7640
Joe Onorato8a9b2202010-02-26 18:56:32 -08007641 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007642 TAG, "Exit animation finished in " + this
7643 + ": remove=" + mRemoveOnExit);
7644 if (mSurface != null) {
7645 mDestroySurface.add(this);
7646 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007647 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007648 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 try {
7650 mSurface.hide();
7651 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007652 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007653 }
7654 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 }
7656 mExiting = false;
7657 if (mRemoveOnExit) {
7658 mPendingRemove.add(this);
7659 mRemoveOnExit = false;
7660 }
7661 }
Romain Guy06882f82009-06-10 13:36:04 -07007662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007663 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7664 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7665 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7666 if (dtdx < -.000001f || dtdx > .000001f) return false;
7667 if (dsdy < -.000001f || dsdy > .000001f) return false;
7668 return true;
7669 }
Romain Guy06882f82009-06-10 13:36:04 -07007670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 void computeShownFrameLocked() {
7672 final boolean selfTransformation = mHasLocalTransformation;
7673 Transformation attachedTransformation =
7674 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7675 ? mAttachedWindow.mTransformation : null;
7676 Transformation appTransformation =
7677 (mAppToken != null && mAppToken.hasTransformation)
7678 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007679
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007680 // Wallpapers are animated based on the "real" window they
7681 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007682 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007683 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007684 if (mWallpaperTarget.mHasLocalTransformation &&
7685 mWallpaperTarget.mAnimation != null &&
7686 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007687 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007688 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007689 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007690 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007691 }
7692 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007693 mWallpaperTarget.mAppToken.hasTransformation &&
7694 mWallpaperTarget.mAppToken.animation != null &&
7695 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007696 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007697 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007698 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007699 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007700 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007701 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007702
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007703 final boolean screenAnimation = mScreenRotationAnimation != null
7704 && mScreenRotationAnimation.isAnimating();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 if (selfTransformation || attachedTransformation != null
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007706 || appTransformation != null || screenAnimation) {
Romain Guy06882f82009-06-10 13:36:04 -07007707 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007708 final Rect frame = mFrame;
7709 final float tmpFloats[] = mTmpFloats;
7710 final Matrix tmpMatrix = mTmpMatrix;
7711
7712 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007713 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007715 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007717 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007719 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 }
7721 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007722 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007723 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007724 if (screenAnimation) {
7725 tmpMatrix.postConcat(
7726 mScreenRotationAnimation.getEnterTransformation().getMatrix());
7727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007728
7729 // "convert" it into SurfaceFlinger's format
7730 // (a 2x2 matrix + an offset)
7731 // Here we must not transform the position of the surface
7732 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007733 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007734
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007735 mHaveMatrix = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 tmpMatrix.getValues(tmpFloats);
7737 mDsDx = tmpFloats[Matrix.MSCALE_X];
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007738 mDtDx = tmpFloats[Matrix.MSKEW_Y];
7739 mDsDy = tmpFloats[Matrix.MSKEW_X];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007740 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007741 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7742 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007743 int w = frame.width();
7744 int h = frame.height();
7745 mShownFrame.set(x, y, x+w, y+h);
7746
7747 // Now set the alpha... but because our current hardware
7748 // can't do alpha transformation on a non-opaque surface,
7749 // turn it off if we are running an animation that is also
7750 // transforming since it is more important to have that
7751 // animation be smooth.
7752 mShownAlpha = mAlpha;
7753 if (!mLimitedAlphaCompositing
7754 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7755 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7756 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007757 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007758 if (selfTransformation) {
7759 mShownAlpha *= mTransformation.getAlpha();
7760 }
7761 if (attachedTransformation != null) {
7762 mShownAlpha *= attachedTransformation.getAlpha();
7763 }
7764 if (appTransformation != null) {
7765 mShownAlpha *= appTransformation.getAlpha();
7766 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007767 if (screenAnimation) {
7768 mShownAlpha *=
7769 mScreenRotationAnimation.getEnterTransformation().getAlpha();
7770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007771 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007772 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 }
Romain Guy06882f82009-06-10 13:36:04 -07007774
Joe Onorato8a9b2202010-02-26 18:56:32 -08007775 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007776 TAG, "Continuing animation in " + this +
7777 ": " + mShownFrame +
7778 ", alpha=" + mTransformation.getAlpha());
7779 return;
7780 }
Romain Guy06882f82009-06-10 13:36:04 -07007781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007783 if (mXOffset != 0 || mYOffset != 0) {
7784 mShownFrame.offset(mXOffset, mYOffset);
7785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 mShownAlpha = mAlpha;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007787 mHaveMatrix = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007788 mDsDx = 1;
7789 mDtDx = 0;
7790 mDsDy = 0;
7791 mDtDy = 1;
7792 }
Romain Guy06882f82009-06-10 13:36:04 -07007793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007794 /**
7795 * Is this window visible? It is not visible if there is no
7796 * surface, or we are in the process of running an exit animation
7797 * that will remove the surface, or its app token has been hidden.
7798 */
7799 public boolean isVisibleLw() {
7800 final AppWindowToken atoken = mAppToken;
7801 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7802 && (atoken == null || !atoken.hiddenRequested)
7803 && !mExiting && !mDestroying;
7804 }
7805
7806 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007807 * Like {@link #isVisibleLw}, but also counts a window that is currently
7808 * "hidden" behind the keyguard as visible. This allows us to apply
7809 * things like window flags that impact the keyguard.
7810 * XXX I am starting to think we need to have ANOTHER visibility flag
7811 * for this "hidden behind keyguard" state rather than overloading
7812 * mPolicyVisibility. Ungh.
7813 */
7814 public boolean isVisibleOrBehindKeyguardLw() {
7815 final AppWindowToken atoken = mAppToken;
7816 return mSurface != null && !mAttachedHidden
7817 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007818 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007819 && !mExiting && !mDestroying;
7820 }
7821
7822 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 * Is this window visible, ignoring its app token? It is not visible
7824 * if there is no surface, or we are in the process of running an exit animation
7825 * that will remove the surface.
7826 */
7827 public boolean isWinVisibleLw() {
7828 final AppWindowToken atoken = mAppToken;
7829 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7830 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7831 && !mExiting && !mDestroying;
7832 }
7833
7834 /**
7835 * The same as isVisible(), but follows the current hidden state of
7836 * the associated app token, not the pending requested hidden state.
7837 */
7838 boolean isVisibleNow() {
7839 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007840 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 }
7842
7843 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007844 * Can this window possibly be a drag/drop target? The test here is
7845 * a combination of the above "visible now" with the check that the
7846 * Input Manager uses when discarding windows from input consideration.
7847 */
7848 boolean isPotentialDragTarget() {
7849 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7850 }
7851
7852 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 * Same as isVisible(), but we also count it as visible between the
7854 * call to IWindowSession.add() and the first relayout().
7855 */
7856 boolean isVisibleOrAdding() {
7857 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007858 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7860 && mPolicyVisibility && !mAttachedHidden
7861 && (atoken == null || !atoken.hiddenRequested)
7862 && !mExiting && !mDestroying;
7863 }
7864
7865 /**
7866 * Is this window currently on-screen? It is on-screen either if it
7867 * is visible or it is currently running an animation before no longer
7868 * being visible.
7869 */
7870 boolean isOnScreen() {
7871 final AppWindowToken atoken = mAppToken;
7872 if (atoken != null) {
7873 return mSurface != null && mPolicyVisibility && !mDestroying
7874 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007875 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 } else {
7877 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007878 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007879 }
7880 }
Romain Guy06882f82009-06-10 13:36:04 -07007881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007882 /**
7883 * Like isOnScreen(), but we don't return true if the window is part
7884 * of a transition that has not yet been started.
7885 */
7886 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007887 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007888 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007889 return false;
7890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007892 final boolean animating = atoken != null
7893 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007895 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7896 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007897 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 }
7899
7900 /** Is the window or its container currently animating? */
7901 boolean isAnimating() {
7902 final WindowState attached = mAttachedWindow;
7903 final AppWindowToken atoken = mAppToken;
7904 return mAnimation != null
7905 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007906 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907 (atoken.animation != null
7908 || atoken.inPendingTransaction));
7909 }
7910
7911 /** Is this window currently animating? */
7912 boolean isWindowAnimating() {
7913 return mAnimation != null;
7914 }
7915
7916 /**
7917 * Like isOnScreen, but returns false if the surface hasn't yet
7918 * been drawn.
7919 */
7920 public boolean isDisplayedLw() {
7921 final AppWindowToken atoken = mAppToken;
7922 return mSurface != null && mPolicyVisibility && !mDestroying
7923 && !mDrawPending && !mCommitDrawPending
7924 && ((!mAttachedHidden &&
7925 (atoken == null || !atoken.hiddenRequested))
7926 || mAnimating);
7927 }
7928
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007929 /**
7930 * Returns true if the window has a surface that it has drawn a
7931 * complete UI in to.
7932 */
7933 public boolean isDrawnLw() {
7934 final AppWindowToken atoken = mAppToken;
7935 return mSurface != null && !mDestroying
7936 && !mDrawPending && !mCommitDrawPending;
7937 }
7938
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007939 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007940 * Return true if the window is opaque and fully drawn. This indicates
7941 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007942 */
7943 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007944 return (mAttrs.format == PixelFormat.OPAQUE
7945 || mAttrs.type == TYPE_WALLPAPER)
7946 && mSurface != null && mAnimation == null
7947 && (mAppToken == null || mAppToken.animation == null)
7948 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007949 }
7950
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007951 /**
7952 * Return whether this window is wanting to have a translation
7953 * animation applied to it for an in-progress move. (Only makes
7954 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
7955 */
7956 boolean shouldAnimateMove() {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007957 return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007958 && (mFrame.top != mLastFrame.top
7959 || mFrame.left != mLastFrame.left)
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007960 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007961 && mPolicy.isScreenOn();
7962 }
7963
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007964 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7965 return
7966 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007967 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7968 // only if it's visible
7969 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007970 // and only if the application fills the compatible screen
7971 mFrame.left <= mCompatibleScreenFrame.left &&
7972 mFrame.top <= mCompatibleScreenFrame.top &&
7973 mFrame.right >= mCompatibleScreenFrame.right &&
7974 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007975 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007976 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007977 }
7978
7979 boolean isFullscreen(int screenWidth, int screenHeight) {
7980 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007981 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007982 }
7983
7984 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007985 disposeInputChannel();
7986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 if (mAttachedWindow != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007988 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 mAttachedWindow.mChildWindows.remove(this);
7990 }
7991 destroySurfaceLocked();
7992 mSession.windowRemovedLocked();
7993 try {
7994 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7995 } catch (RuntimeException e) {
7996 // Ignore if it has already been removed (usually because
7997 // we are doing this as part of processing a death note.)
7998 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007999 }
8000
8001 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008002 if (mInputChannel != null) {
8003 mInputManager.unregisterInputChannel(mInputChannel);
8004
8005 mInputChannel.dispose();
8006 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008 }
8009
8010 private class DeathRecipient implements IBinder.DeathRecipient {
8011 public void binderDied() {
8012 try {
8013 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008014 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008015 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008016 if (win != null) {
8017 removeWindowLocked(mSession, win);
8018 }
8019 }
8020 } catch (IllegalArgumentException ex) {
8021 // This will happen if the window has already been
8022 // removed.
8023 }
8024 }
8025 }
8026
8027 /** Returns true if this window desires key events. */
8028 public final boolean canReceiveKeys() {
8029 return isVisibleOrAdding()
8030 && (mViewVisibility == View.VISIBLE)
8031 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8032 }
8033
8034 public boolean hasDrawnLw() {
8035 return mHasDrawn;
8036 }
8037
8038 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008039 return showLw(doAnimation, true);
8040 }
8041
8042 boolean showLw(boolean doAnimation, boolean requestAnim) {
8043 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8044 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008046 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008047 if (doAnimation) {
8048 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8049 + mPolicyVisibility + " mAnimation=" + mAnimation);
8050 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8051 doAnimation = false;
8052 } else if (mPolicyVisibility && mAnimation == null) {
8053 // Check for the case where we are currently visible and
8054 // not animating; we do not want to do animation at such a
8055 // point to become visible when we already are.
8056 doAnimation = false;
8057 }
8058 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008059 mPolicyVisibility = true;
8060 mPolicyVisibilityAfterAnim = true;
8061 if (doAnimation) {
8062 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8063 }
8064 if (requestAnim) {
8065 requestAnimationLocked(0);
8066 }
8067 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 }
8069
8070 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008071 return hideLw(doAnimation, true);
8072 }
8073
8074 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008075 if (doAnimation) {
8076 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8077 doAnimation = false;
8078 }
8079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8081 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008082 if (!current) {
8083 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008084 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008085 if (doAnimation) {
8086 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8087 if (mAnimation == null) {
8088 doAnimation = false;
8089 }
8090 }
8091 if (doAnimation) {
8092 mPolicyVisibilityAfterAnim = false;
8093 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008094 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008095 mPolicyVisibilityAfterAnim = false;
8096 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008097 // Window is no longer visible -- make sure if we were waiting
8098 // for it to be displayed before enabling the display, that
8099 // we allow the display to be enabled now.
8100 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008101 if (mCurrentFocus == this) {
8102 mFocusMayChange = true;
8103 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008104 }
8105 if (requestAnim) {
8106 requestAnimationLocked(0);
8107 }
8108 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008109 }
8110
8111 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008112 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8113 pw.print(" mClient="); pw.println(mClient.asBinder());
8114 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8115 if (mAttachedWindow != null || mLayoutAttached) {
8116 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8117 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8118 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008119 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8120 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8121 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008122 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8123 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008124 }
8125 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8126 pw.print(" mSubLayer="); pw.print(mSubLayer);
8127 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8128 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8129 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8130 pw.print("="); pw.print(mAnimLayer);
8131 pw.print(" mLastLayer="); pw.println(mLastLayer);
8132 if (mSurface != null) {
8133 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008134 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8135 pw.print(" layer="); pw.print(mSurfaceLayer);
8136 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8137 pw.print(" rect=("); pw.print(mSurfaceX);
8138 pw.print(","); pw.print(mSurfaceY);
8139 pw.print(") "); pw.print(mSurfaceW);
8140 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008141 }
8142 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8143 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8144 if (mAppToken != null) {
8145 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8146 }
8147 if (mTargetAppToken != null) {
8148 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8149 }
8150 pw.print(prefix); pw.print("mViewVisibility=0x");
8151 pw.print(Integer.toHexString(mViewVisibility));
8152 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008153 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8154 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008155 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8156 pw.print(prefix); pw.print("mPolicyVisibility=");
8157 pw.print(mPolicyVisibility);
8158 pw.print(" mPolicyVisibilityAfterAnim=");
8159 pw.print(mPolicyVisibilityAfterAnim);
8160 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8161 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008162 if (!mRelayoutCalled) {
8163 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8164 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008165 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008166 pw.print(" h="); pw.print(mRequestedHeight);
8167 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008168 if (mXOffset != 0 || mYOffset != 0) {
8169 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8170 pw.print(" y="); pw.println(mYOffset);
8171 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008172 pw.print(prefix); pw.print("mGivenContentInsets=");
8173 mGivenContentInsets.printShortString(pw);
8174 pw.print(" mGivenVisibleInsets=");
8175 mGivenVisibleInsets.printShortString(pw);
8176 pw.println();
8177 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8178 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8179 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8180 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008181 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008182 pw.print(prefix); pw.print("mShownFrame=");
8183 mShownFrame.printShortString(pw);
8184 pw.print(" last="); mLastShownFrame.printShortString(pw);
8185 pw.println();
8186 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8187 pw.print(" last="); mLastFrame.printShortString(pw);
8188 pw.println();
8189 pw.print(prefix); pw.print("mContainingFrame=");
8190 mContainingFrame.printShortString(pw);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008191 pw.print(" mParentFrame=");
8192 mParentFrame.printShortString(pw);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008193 pw.print(" mDisplayFrame=");
8194 mDisplayFrame.printShortString(pw);
8195 pw.println();
8196 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8197 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8198 pw.println();
8199 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8200 pw.print(" last="); mLastContentInsets.printShortString(pw);
8201 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8202 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8203 pw.println();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008204 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8205 || mAnimation != null) {
8206 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8207 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8208 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8209 pw.print(" mAnimation="); pw.println(mAnimation);
8210 }
8211 if (mHasTransformation || mHasLocalTransformation) {
8212 pw.print(prefix); pw.print("XForm: has=");
8213 pw.print(mHasTransformation);
8214 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8215 pw.print(" "); mTransformation.printShortString(pw);
8216 pw.println();
8217 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008218 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8219 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8220 pw.print(" mAlpha="); pw.print(mAlpha);
8221 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8222 }
8223 if (mHaveMatrix) {
8224 pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
8225 pw.print(" mDtDx="); pw.print(mDtDx);
8226 pw.print(" mDsDy="); pw.print(mDsDy);
8227 pw.print(" mDtDy="); pw.println(mDtDy);
8228 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008229 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8230 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8231 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8232 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8233 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8234 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8235 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8236 pw.print(" mDestroying="); pw.print(mDestroying);
8237 pw.print(" mRemoved="); pw.println(mRemoved);
8238 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008239 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008240 pw.print(prefix); pw.print("mOrientationChanging=");
8241 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008242 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8243 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008244 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008245 if (mHScale != 1 || mVScale != 1) {
8246 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8247 pw.print(" mVScale="); pw.println(mVScale);
8248 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008249 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008250 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8251 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8252 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008253 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8254 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8255 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008257 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008258
8259 String makeInputChannelName() {
8260 return Integer.toHexString(System.identityHashCode(this))
8261 + " " + mAttrs.getTitle();
8262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008263
8264 @Override
8265 public String toString() {
Mattias Petersson1622eee2010-12-21 10:15:11 +01008266 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
8267 || mWasPaused != mToken.paused) {
8268 mLastTitle = mAttrs.getTitle();
8269 mWasPaused = mToken.paused;
8270 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
8271 + " " + mLastTitle + " paused=" + mWasPaused + "}";
8272 }
8273 return mStringNameCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008274 }
8275 }
Romain Guy06882f82009-06-10 13:36:04 -07008276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008277 // -------------------------------------------------------------
8278 // Window Token State
8279 // -------------------------------------------------------------
8280
8281 class WindowToken {
8282 // The actual token.
8283 final IBinder token;
8284
8285 // The type of window this token is for, as per WindowManager.LayoutParams.
8286 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008288 // Set if this token was explicitly added by a client, so should
8289 // not be removed when all windows are removed.
8290 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008291
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008292 // For printing.
8293 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008295 // If this is an AppWindowToken, this is non-null.
8296 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 // All of the windows associated with this token.
8299 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8300
8301 // Is key dispatching paused for this token?
8302 boolean paused = false;
8303
8304 // Should this token's windows be hidden?
8305 boolean hidden;
8306
8307 // Temporary for finding which tokens no longer have visible windows.
8308 boolean hasVisible;
8309
Dianne Hackborna8f60182009-09-01 19:01:50 -07008310 // Set to true when this token is in a pending transaction where it
8311 // will be shown.
8312 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008313
Dianne Hackborna8f60182009-09-01 19:01:50 -07008314 // Set to true when this token is in a pending transaction where it
8315 // will be hidden.
8316 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008317
Dianne Hackborna8f60182009-09-01 19:01:50 -07008318 // Set to true when this token is in a pending transaction where its
8319 // windows will be put to the bottom of the list.
8320 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008321
Dianne Hackborna8f60182009-09-01 19:01:50 -07008322 // Set to true when this token is in a pending transaction where its
8323 // windows will be put to the top of the list.
8324 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 WindowToken(IBinder _token, int type, boolean _explicit) {
8327 token = _token;
8328 windowType = type;
8329 explicit = _explicit;
8330 }
8331
8332 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008333 pw.print(prefix); pw.print("token="); pw.println(token);
8334 pw.print(prefix); pw.print("windows="); pw.println(windows);
8335 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8336 pw.print(" hidden="); pw.print(hidden);
8337 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008338 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8339 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8340 pw.print(" waitingToHide="); pw.print(waitingToHide);
8341 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8342 pw.print(" sendingToTop="); pw.println(sendingToTop);
8343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008344 }
8345
8346 @Override
8347 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008348 if (stringName == null) {
8349 StringBuilder sb = new StringBuilder();
8350 sb.append("WindowToken{");
8351 sb.append(Integer.toHexString(System.identityHashCode(this)));
8352 sb.append(" token="); sb.append(token); sb.append('}');
8353 stringName = sb.toString();
8354 }
8355 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356 }
8357 };
8358
8359 class AppWindowToken extends WindowToken {
8360 // Non-null only for application tokens.
8361 final IApplicationToken appToken;
8362
8363 // All of the windows and child windows that are included in this
8364 // application token. Note this list is NOT sorted!
8365 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8366
8367 int groupId = -1;
8368 boolean appFullscreen;
8369 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008370
8371 // The input dispatching timeout for this application token in nanoseconds.
8372 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008374 // These are used for determining when all windows associated with
8375 // an activity have been drawn, so they can be made visible together
8376 // at the same time.
8377 int lastTransactionSequence = mTransactionSequence-1;
8378 int numInterestingWindows;
8379 int numDrawnWindows;
8380 boolean inPendingTransaction;
8381 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383 // Is this token going to be hidden in a little while? If so, it
8384 // won't be taken into account for setting the screen orientation.
8385 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387 // Is this window's surface needed? This is almost like hidden, except
8388 // it will sometimes be true a little earlier: when the token has
8389 // been shown, but is still waiting for its app transition to execute
8390 // before making its windows shown.
8391 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008393 // Have we told the window clients to hide themselves?
8394 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396 // Last visibility state we reported to the app token.
8397 boolean reportedVisible;
8398
8399 // Set to true when the token has been removed from the window mgr.
8400 boolean removed;
8401
8402 // Have we been asked to have this token keep the screen frozen?
8403 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 boolean animating;
8406 Animation animation;
8407 boolean hasTransformation;
8408 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008410 // Offset to the window of all layers in the token, for use by
8411 // AppWindowToken animations.
8412 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008414 // Information about an application starting window if displayed.
8415 StartingData startingData;
8416 WindowState startingWindow;
8417 View startingView;
8418 boolean startingDisplayed;
8419 boolean startingMoved;
8420 boolean firstWindowDrawn;
8421
Jeff Brown928e0542011-01-10 11:17:36 -08008422 // Input application handle used by the input dispatcher.
8423 InputApplicationHandle mInputApplicationHandle;
8424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 AppWindowToken(IApplicationToken _token) {
8426 super(_token.asBinder(),
8427 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8428 appWindowToken = this;
8429 appToken = _token;
Jeff Brown928e0542011-01-10 11:17:36 -08008430 mInputApplicationHandle = new InputApplicationHandle(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008431 }
Romain Guy06882f82009-06-10 13:36:04 -07008432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008434 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008435 TAG, "Setting animation in " + this + ": " + anim);
8436 animation = anim;
8437 animating = false;
8438 anim.restrictDuration(MAX_ANIMATION_DURATION);
8439 anim.scaleCurrentDuration(mTransitionAnimationScale);
8440 int zorder = anim.getZAdjustment();
8441 int adj = 0;
8442 if (zorder == Animation.ZORDER_TOP) {
8443 adj = TYPE_LAYER_OFFSET;
8444 } else if (zorder == Animation.ZORDER_BOTTOM) {
8445 adj = -TYPE_LAYER_OFFSET;
8446 }
Romain Guy06882f82009-06-10 13:36:04 -07008447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008448 if (animLayerAdjustment != adj) {
8449 animLayerAdjustment = adj;
8450 updateLayers();
8451 }
8452 }
Romain Guy06882f82009-06-10 13:36:04 -07008453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008454 public void setDummyAnimation() {
8455 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008456 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 TAG, "Setting dummy animation in " + this);
8458 animation = sDummyAnimation;
8459 }
8460 }
8461
8462 public void clearAnimation() {
8463 if (animation != null) {
8464 animation = null;
8465 animating = true;
8466 }
8467 }
Romain Guy06882f82009-06-10 13:36:04 -07008468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469 void updateLayers() {
8470 final int N = allAppWindows.size();
8471 final int adj = animLayerAdjustment;
8472 for (int i=0; i<N; i++) {
8473 WindowState w = allAppWindows.get(i);
8474 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008475 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008476 + w.mAnimLayer);
8477 if (w == mInputMethodTarget) {
8478 setInputMethodAnimLayerAdjustment(adj);
8479 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008480 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008481 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008483 }
8484 }
Romain Guy06882f82009-06-10 13:36:04 -07008485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008486 void sendAppVisibilityToClients() {
8487 final int N = allAppWindows.size();
8488 for (int i=0; i<N; i++) {
8489 WindowState win = allAppWindows.get(i);
8490 if (win == startingWindow && clientHidden) {
8491 // Don't hide the starting window.
8492 continue;
8493 }
8494 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008495 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008496 "Setting visibility of " + win + ": " + (!clientHidden));
8497 win.mClient.dispatchAppVisibility(!clientHidden);
8498 } catch (RemoteException e) {
8499 }
8500 }
8501 }
Romain Guy06882f82009-06-10 13:36:04 -07008502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008503 void showAllWindowsLocked() {
8504 final int NW = allAppWindows.size();
8505 for (int i=0; i<NW; i++) {
8506 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008507 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 "performing show on: " + w);
8509 w.performShowLocked();
8510 }
8511 }
Romain Guy06882f82009-06-10 13:36:04 -07008512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 // This must be called while inside a transaction.
8514 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008515 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008516 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008518 if (animation == sDummyAnimation) {
8519 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008520 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 // when it is really time to animate, this will be set to
8522 // a real animation and the next call will execute normally.
8523 return false;
8524 }
Romain Guy06882f82009-06-10 13:36:04 -07008525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8527 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008528 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008529 TAG, "Starting animation in " + this +
8530 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8531 + " scale=" + mTransitionAnimationScale
8532 + " allDrawn=" + allDrawn + " animating=" + animating);
8533 animation.initialize(dw, dh, dw, dh);
8534 animation.setStartTime(currentTime);
8535 animating = true;
8536 }
8537 transformation.clear();
8538 final boolean more = animation.getTransformation(
8539 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008540 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 TAG, "Stepped animation in " + this +
8542 ": more=" + more + ", xform=" + transformation);
8543 if (more) {
8544 // we're done!
8545 hasTransformation = true;
8546 return true;
8547 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008548 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549 TAG, "Finished animation in " + this +
8550 " @ " + currentTime);
8551 animation = null;
8552 }
8553 } else if (animation != null) {
8554 // If the display is frozen, and there is a pending animation,
8555 // clear it and make sure we run the cleanup code.
8556 animating = true;
8557 animation = null;
8558 }
8559
8560 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008562 if (!animating) {
8563 return false;
8564 }
8565
8566 clearAnimation();
8567 animating = false;
8568 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8569 moveInputMethodWindowsIfNeededLocked(true);
8570 }
Romain Guy06882f82009-06-10 13:36:04 -07008571
Joe Onorato8a9b2202010-02-26 18:56:32 -08008572 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008573 TAG, "Animation done in " + this
8574 + ": reportedVisible=" + reportedVisible);
8575
8576 transformation.clear();
8577 if (animLayerAdjustment != 0) {
8578 animLayerAdjustment = 0;
8579 updateLayers();
8580 }
Romain Guy06882f82009-06-10 13:36:04 -07008581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 final int N = windows.size();
8583 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008584 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 }
8586 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008588 return false;
8589 }
8590
8591 void updateReportedVisibilityLocked() {
8592 if (appToken == null) {
8593 return;
8594 }
Romain Guy06882f82009-06-10 13:36:04 -07008595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008596 int numInteresting = 0;
8597 int numVisible = 0;
8598 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008599
Joe Onorato8a9b2202010-02-26 18:56:32 -08008600 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 final int N = allAppWindows.size();
8602 for (int i=0; i<N; i++) {
8603 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008604 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008605 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008606 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8607 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 continue;
8609 }
8610 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008611 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008612 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008614 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008615 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008616 + " pv=" + win.mPolicyVisibility
8617 + " dp=" + win.mDrawPending
8618 + " cdp=" + win.mCommitDrawPending
8619 + " ah=" + win.mAttachedHidden
8620 + " th="
8621 + (win.mAppToken != null
8622 ? win.mAppToken.hiddenRequested : false)
8623 + " a=" + win.mAnimating);
8624 }
8625 }
8626 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008627 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 if (!win.isAnimating()) {
8629 numVisible++;
8630 }
8631 nowGone = false;
8632 } else if (win.isAnimating()) {
8633 nowGone = false;
8634 }
8635 }
Romain Guy06882f82009-06-10 13:36:04 -07008636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008638 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008639 + numInteresting + " visible=" + numVisible);
8640 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008641 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008642 TAG, "Visibility changed in " + this
8643 + ": vis=" + nowVisible);
8644 reportedVisible = nowVisible;
8645 Message m = mH.obtainMessage(
8646 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8647 nowVisible ? 1 : 0,
8648 nowGone ? 1 : 0,
8649 this);
8650 mH.sendMessage(m);
8651 }
8652 }
Romain Guy06882f82009-06-10 13:36:04 -07008653
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008654 WindowState findMainWindow() {
8655 int j = windows.size();
8656 while (j > 0) {
8657 j--;
8658 WindowState win = windows.get(j);
8659 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8660 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8661 return win;
8662 }
8663 }
8664 return null;
8665 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667 void dump(PrintWriter pw, String prefix) {
8668 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008669 if (appToken != null) {
8670 pw.print(prefix); pw.println("app=true");
8671 }
8672 if (allAppWindows.size() > 0) {
8673 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8674 }
8675 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008676 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008677 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8678 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8679 pw.print(" clientHidden="); pw.print(clientHidden);
8680 pw.print(" willBeHidden="); pw.print(willBeHidden);
8681 pw.print(" reportedVisible="); pw.println(reportedVisible);
8682 if (paused || freezingScreen) {
8683 pw.print(prefix); pw.print("paused="); pw.print(paused);
8684 pw.print(" freezingScreen="); pw.println(freezingScreen);
8685 }
8686 if (numInterestingWindows != 0 || numDrawnWindows != 0
8687 || inPendingTransaction || allDrawn) {
8688 pw.print(prefix); pw.print("numInterestingWindows=");
8689 pw.print(numInterestingWindows);
8690 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8691 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8692 pw.print(" allDrawn="); pw.println(allDrawn);
8693 }
8694 if (animating || animation != null) {
8695 pw.print(prefix); pw.print("animating="); pw.print(animating);
8696 pw.print(" animation="); pw.println(animation);
8697 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008698 if (hasTransformation) {
8699 pw.print(prefix); pw.print("XForm: ");
8700 transformation.printShortString(pw);
8701 pw.println();
8702 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008703 if (animLayerAdjustment != 0) {
8704 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8705 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008706 if (startingData != null || removed || firstWindowDrawn) {
8707 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8708 pw.print(" removed="); pw.print(removed);
8709 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8710 }
8711 if (startingWindow != null || startingView != null
8712 || startingDisplayed || startingMoved) {
8713 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8714 pw.print(" startingView="); pw.print(startingView);
8715 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8716 pw.print(" startingMoved"); pw.println(startingMoved);
8717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008718 }
8719
8720 @Override
8721 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008722 if (stringName == null) {
8723 StringBuilder sb = new StringBuilder();
8724 sb.append("AppWindowToken{");
8725 sb.append(Integer.toHexString(System.identityHashCode(this)));
8726 sb.append(" token="); sb.append(token); sb.append('}');
8727 stringName = sb.toString();
8728 }
8729 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008730 }
8731 }
Romain Guy06882f82009-06-10 13:36:04 -07008732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 // -------------------------------------------------------------
8734 // DummyAnimation
8735 // -------------------------------------------------------------
8736
8737 // This is an animation that does nothing: it just immediately finishes
8738 // itself every time it is called. It is used as a stub animation in cases
8739 // where we want to synchronize multiple things that may be animating.
8740 static final class DummyAnimation extends Animation {
8741 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8742 return false;
8743 }
8744 }
8745 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 // -------------------------------------------------------------
8748 // Async Handler
8749 // -------------------------------------------------------------
8750
8751 static final class StartingData {
8752 final String pkg;
8753 final int theme;
8754 final CharSequence nonLocalizedLabel;
8755 final int labelRes;
8756 final int icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008757 final int windowFlags;
Romain Guy06882f82009-06-10 13:36:04 -07008758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008760 int _labelRes, int _icon, int _windowFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 pkg = _pkg;
8762 theme = _theme;
8763 nonLocalizedLabel = _nonLocalizedLabel;
8764 labelRes = _labelRes;
8765 icon = _icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008766 windowFlags = _windowFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008767 }
8768 }
8769
8770 private final class H extends Handler {
8771 public static final int REPORT_FOCUS_CHANGE = 2;
8772 public static final int REPORT_LOSING_FOCUS = 3;
8773 public static final int ANIMATE = 4;
8774 public static final int ADD_STARTING = 5;
8775 public static final int REMOVE_STARTING = 6;
8776 public static final int FINISHED_STARTING = 7;
8777 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8779 public static final int HOLD_SCREEN_CHANGED = 12;
8780 public static final int APP_TRANSITION_TIMEOUT = 13;
8781 public static final int PERSIST_ANIMATION_SCALE = 14;
8782 public static final int FORCE_GC = 15;
8783 public static final int ENABLE_SCREEN = 16;
8784 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008785 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008786 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008787 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008788 public static final int DRAG_END_TIMEOUT = 21;
Romain Guy06882f82009-06-10 13:36:04 -07008789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008792 public H() {
8793 }
Romain Guy06882f82009-06-10 13:36:04 -07008794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 @Override
8796 public void handleMessage(Message msg) {
8797 switch (msg.what) {
8798 case REPORT_FOCUS_CHANGE: {
8799 WindowState lastFocus;
8800 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008802 synchronized(mWindowMap) {
8803 lastFocus = mLastFocus;
8804 newFocus = mCurrentFocus;
8805 if (lastFocus == newFocus) {
8806 // Focus is not changing, so nothing to do.
8807 return;
8808 }
8809 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008810 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008811 // + " to " + newFocus);
8812 if (newFocus != null && lastFocus != null
8813 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008814 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 mLosingFocus.add(lastFocus);
8816 lastFocus = null;
8817 }
8818 }
8819
8820 if (lastFocus != newFocus) {
8821 //System.out.println("Changing focus from " + lastFocus
8822 // + " to " + newFocus);
8823 if (newFocus != null) {
8824 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008825 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8827 } catch (RemoteException e) {
8828 // Ignore if process has died.
8829 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008830 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008831 }
8832
8833 if (lastFocus != null) {
8834 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008835 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008836 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8837 } catch (RemoteException e) {
8838 // Ignore if process has died.
8839 }
8840 }
8841 }
8842 } break;
8843
8844 case REPORT_LOSING_FOCUS: {
8845 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008847 synchronized(mWindowMap) {
8848 losers = mLosingFocus;
8849 mLosingFocus = new ArrayList<WindowState>();
8850 }
8851
8852 final int N = losers.size();
8853 for (int i=0; i<N; i++) {
8854 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008855 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8857 } catch (RemoteException e) {
8858 // Ignore if process has died.
8859 }
8860 }
8861 } break;
8862
8863 case ANIMATE: {
8864 synchronized(mWindowMap) {
8865 mAnimationPending = false;
8866 performLayoutAndPlaceSurfacesLocked();
8867 }
8868 } break;
8869
8870 case ADD_STARTING: {
8871 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8872 final StartingData sd = wtoken.startingData;
8873
8874 if (sd == null) {
8875 // Animation has been canceled... do nothing.
8876 return;
8877 }
Romain Guy06882f82009-06-10 13:36:04 -07008878
Joe Onorato8a9b2202010-02-26 18:56:32 -08008879 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008880 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 View view = null;
8883 try {
8884 view = mPolicy.addStartingWindow(
8885 wtoken.token, sd.pkg,
8886 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008887 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008889 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 }
8891
8892 if (view != null) {
8893 boolean abort = false;
8894
8895 synchronized(mWindowMap) {
8896 if (wtoken.removed || wtoken.startingData == null) {
8897 // If the window was successfully added, then
8898 // we need to remove it.
8899 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008900 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008901 "Aborted starting " + wtoken
8902 + ": removed=" + wtoken.removed
8903 + " startingData=" + wtoken.startingData);
8904 wtoken.startingWindow = null;
8905 wtoken.startingData = null;
8906 abort = true;
8907 }
8908 } else {
8909 wtoken.startingView = view;
8910 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008911 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008912 "Added starting " + wtoken
8913 + ": startingWindow="
8914 + wtoken.startingWindow + " startingView="
8915 + wtoken.startingView);
8916 }
8917
8918 if (abort) {
8919 try {
8920 mPolicy.removeStartingWindow(wtoken.token, view);
8921 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008922 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008923 }
8924 }
8925 }
8926 } break;
8927
8928 case REMOVE_STARTING: {
8929 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8930 IBinder token = null;
8931 View view = null;
8932 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008933 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008934 + wtoken + ": startingWindow="
8935 + wtoken.startingWindow + " startingView="
8936 + wtoken.startingView);
8937 if (wtoken.startingWindow != null) {
8938 view = wtoken.startingView;
8939 token = wtoken.token;
8940 wtoken.startingData = null;
8941 wtoken.startingView = null;
8942 wtoken.startingWindow = null;
8943 }
8944 }
8945 if (view != null) {
8946 try {
8947 mPolicy.removeStartingWindow(token, view);
8948 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008949 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008950 }
8951 }
8952 } break;
8953
8954 case FINISHED_STARTING: {
8955 IBinder token = null;
8956 View view = null;
8957 while (true) {
8958 synchronized (mWindowMap) {
8959 final int N = mFinishedStarting.size();
8960 if (N <= 0) {
8961 break;
8962 }
8963 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8964
Joe Onorato8a9b2202010-02-26 18:56:32 -08008965 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008966 "Finished starting " + wtoken
8967 + ": startingWindow=" + wtoken.startingWindow
8968 + " startingView=" + wtoken.startingView);
8969
8970 if (wtoken.startingWindow == null) {
8971 continue;
8972 }
8973
8974 view = wtoken.startingView;
8975 token = wtoken.token;
8976 wtoken.startingData = null;
8977 wtoken.startingView = null;
8978 wtoken.startingWindow = null;
8979 }
8980
8981 try {
8982 mPolicy.removeStartingWindow(token, view);
8983 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008984 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 }
8986 }
8987 } break;
8988
8989 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8990 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8991
8992 boolean nowVisible = msg.arg1 != 0;
8993 boolean nowGone = msg.arg2 != 0;
8994
8995 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008996 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008997 TAG, "Reporting visible in " + wtoken
8998 + " visible=" + nowVisible
8999 + " gone=" + nowGone);
9000 if (nowVisible) {
9001 wtoken.appToken.windowsVisible();
9002 } else {
9003 wtoken.appToken.windowsGone();
9004 }
9005 } catch (RemoteException ex) {
9006 }
9007 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 case WINDOW_FREEZE_TIMEOUT: {
9010 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009011 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009012 int i = mWindows.size();
9013 while (i > 0) {
9014 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07009015 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 if (w.mOrientationChanging) {
9017 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009018 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 }
9020 }
9021 performLayoutAndPlaceSurfacesLocked();
9022 }
9023 break;
9024 }
Romain Guy06882f82009-06-10 13:36:04 -07009025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009026 case HOLD_SCREEN_CHANGED: {
9027 Session oldHold;
9028 Session newHold;
9029 synchronized (mWindowMap) {
9030 oldHold = mLastReportedHold;
9031 newHold = (Session)msg.obj;
9032 mLastReportedHold = newHold;
9033 }
Romain Guy06882f82009-06-10 13:36:04 -07009034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 if (oldHold != newHold) {
9036 try {
9037 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009038 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 "window",
9040 BatteryStats.WAKE_TYPE_WINDOW);
9041 }
9042 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009043 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 "window",
9045 BatteryStats.WAKE_TYPE_WINDOW);
9046 }
9047 } catch (RemoteException e) {
9048 }
9049 }
9050 break;
9051 }
Romain Guy06882f82009-06-10 13:36:04 -07009052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009053 case APP_TRANSITION_TIMEOUT: {
9054 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009055 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009056 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009057 "*** APP TRANSITION TIMEOUT");
9058 mAppTransitionReady = true;
9059 mAppTransitionTimeout = true;
9060 performLayoutAndPlaceSurfacesLocked();
9061 }
9062 }
9063 break;
9064 }
Romain Guy06882f82009-06-10 13:36:04 -07009065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009066 case PERSIST_ANIMATION_SCALE: {
9067 Settings.System.putFloat(mContext.getContentResolver(),
9068 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9069 Settings.System.putFloat(mContext.getContentResolver(),
9070 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9071 break;
9072 }
Romain Guy06882f82009-06-10 13:36:04 -07009073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 case FORCE_GC: {
9075 synchronized(mWindowMap) {
9076 if (mAnimationPending) {
9077 // If we are animating, don't do the gc now but
9078 // delay a bit so we don't interrupt the animation.
9079 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9080 2000);
9081 return;
9082 }
9083 // If we are currently rotating the display, it will
9084 // schedule a new message when done.
9085 if (mDisplayFrozen) {
9086 return;
9087 }
9088 mFreezeGcPending = 0;
9089 }
9090 Runtime.getRuntime().gc();
9091 break;
9092 }
Romain Guy06882f82009-06-10 13:36:04 -07009093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009094 case ENABLE_SCREEN: {
9095 performEnableScreen();
9096 break;
9097 }
Romain Guy06882f82009-06-10 13:36:04 -07009098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 case APP_FREEZE_TIMEOUT: {
9100 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009101 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009102 int i = mAppTokens.size();
9103 while (i > 0) {
9104 i--;
9105 AppWindowToken tok = mAppTokens.get(i);
9106 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009107 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 unsetAppFreezingScreenLocked(tok, true, true);
9109 }
9110 }
9111 }
9112 break;
9113 }
Romain Guy06882f82009-06-10 13:36:04 -07009114
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009115 case SEND_NEW_CONFIGURATION: {
9116 removeMessages(SEND_NEW_CONFIGURATION);
9117 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009118 break;
9119 }
Romain Guy06882f82009-06-10 13:36:04 -07009120
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009121 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009122 if (mWindowsChanged) {
9123 synchronized (mWindowMap) {
9124 mWindowsChanged = false;
9125 }
9126 notifyWindowsChanged();
9127 }
9128 break;
9129 }
9130
Christopher Tatea53146c2010-09-07 11:57:52 -07009131 case DRAG_START_TIMEOUT: {
9132 IBinder win = (IBinder)msg.obj;
9133 if (DEBUG_DRAG) {
9134 Slog.w(TAG, "Timeout starting drag by win " + win);
9135 }
9136 synchronized (mWindowMap) {
9137 // !!! TODO: ANR the app that has failed to start the drag in time
9138 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07009139 mDragState.unregister();
9140 mInputMonitor.updateInputWindowsLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07009141 mDragState.reset();
9142 mDragState = null;
9143 }
9144 }
Chris Tated4533f142010-10-19 15:15:08 -07009145 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07009146 }
9147
Chris Tated4533f142010-10-19 15:15:08 -07009148 case DRAG_END_TIMEOUT: {
9149 IBinder win = (IBinder)msg.obj;
9150 if (DEBUG_DRAG) {
9151 Slog.w(TAG, "Timeout ending drag to win " + win);
9152 }
9153 synchronized (mWindowMap) {
9154 // !!! TODO: ANR the drag-receiving app
9155 mDragState.mDragResult = false;
9156 mDragState.endDragLw();
9157 }
9158 break;
9159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009160 }
9161 }
9162 }
9163
9164 // -------------------------------------------------------------
9165 // IWindowManager API
9166 // -------------------------------------------------------------
9167
9168 public IWindowSession openSession(IInputMethodClient client,
9169 IInputContext inputContext) {
9170 if (client == null) throw new IllegalArgumentException("null client");
9171 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009172 Session session = new Session(client, inputContext);
9173 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009174 }
9175
9176 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9177 synchronized (mWindowMap) {
9178 // The focus for the client is the window immediately below
9179 // where we would place the input method window.
9180 int idx = findDesiredInputMethodWindowIndexLocked(false);
9181 WindowState imFocus;
9182 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07009183 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 if (imFocus != null) {
9185 if (imFocus.mSession.mClient != null &&
9186 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9187 return true;
9188 }
9189 }
9190 }
9191 }
9192 return false;
9193 }
Romain Guy06882f82009-06-10 13:36:04 -07009194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009195 // -------------------------------------------------------------
9196 // Internals
9197 // -------------------------------------------------------------
9198
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009199 final WindowState windowForClientLocked(Session session, IWindow client,
9200 boolean throwOnError) {
9201 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 }
Romain Guy06882f82009-06-10 13:36:04 -07009203
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009204 final WindowState windowForClientLocked(Session session, IBinder client,
9205 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009206 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009207 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208 TAG, "Looking up client " + client + ": " + win);
9209 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009210 RuntimeException ex = new IllegalArgumentException(
9211 "Requested window " + client + " does not exist");
9212 if (throwOnError) {
9213 throw ex;
9214 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009215 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009216 return null;
9217 }
9218 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009219 RuntimeException ex = new IllegalArgumentException(
9220 "Requested window " + client + " is in session " +
9221 win.mSession + ", not " + session);
9222 if (throwOnError) {
9223 throw ex;
9224 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009225 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009226 return null;
9227 }
9228
9229 return win;
9230 }
9231
Dianne Hackborna8f60182009-09-01 19:01:50 -07009232 final void rebuildAppWindowListLocked() {
9233 int NW = mWindows.size();
9234 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009235 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009236 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009237
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009238 if (mRebuildTmp.length < NW) {
9239 mRebuildTmp = new WindowState[NW+10];
9240 }
9241
Dianne Hackborna8f60182009-09-01 19:01:50 -07009242 // First remove all existing app windows.
9243 i=0;
9244 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07009245 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009246 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07009247 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009248 win.mRebuilding = true;
9249 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009250 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009251 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009252 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009253 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009254 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009255 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009256 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9257 && lastWallpaper == i-1) {
9258 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009259 }
9260 i++;
9261 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009262
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009263 // The wallpaper window(s) typically live at the bottom of the stack,
9264 // so skip them before adding app tokens.
9265 lastWallpaper++;
9266 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009267
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009268 // First add all of the exiting app tokens... these are no longer
9269 // in the main app list, but still have windows shown. We put them
9270 // in the back because now that the animation is over we no longer
9271 // will care about them.
9272 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009273 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009274 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9275 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009276
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009277 // And add in the still active app tokens in Z order.
9278 NT = mAppTokens.size();
9279 for (int j=0; j<NT; j++) {
9280 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009281 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009282
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009283 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009284 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009285 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009286 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009287 for (i=0; i<numRemoved; i++) {
9288 WindowState ws = mRebuildTmp[i];
9289 if (ws.mRebuilding) {
9290 StringWriter sw = new StringWriter();
9291 PrintWriter pw = new PrintWriter(sw);
9292 ws.dump(pw, "");
9293 pw.flush();
9294 Slog.w(TAG, "This window was lost: " + ws);
9295 Slog.w(TAG, sw.toString());
9296 }
9297 }
9298 Slog.w(TAG, "Current app token list:");
9299 dumpAppTokensLocked();
9300 Slog.w(TAG, "Final window list:");
9301 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009302 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009303 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009305 private final void assignLayersLocked() {
9306 int N = mWindows.size();
9307 int curBaseLayer = 0;
9308 int curLayer = 0;
9309 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009310
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009311 if (DEBUG_LAYERS) {
9312 RuntimeException here = new RuntimeException("here");
9313 here.fillInStackTrace();
9314 Log.v(TAG, "Assigning layers", here);
9315 }
9316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009317 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07009318 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009319 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9320 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 curLayer += WINDOW_LAYER_MULTIPLIER;
9322 w.mLayer = curLayer;
9323 } else {
9324 curBaseLayer = curLayer = w.mBaseLayer;
9325 w.mLayer = curLayer;
9326 }
9327 if (w.mTargetAppToken != null) {
9328 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9329 } else if (w.mAppToken != null) {
9330 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9331 } else {
9332 w.mAnimLayer = w.mLayer;
9333 }
9334 if (w.mIsImWindow) {
9335 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009336 } else if (w.mIsWallpaper) {
9337 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009338 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009339 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 + w.mAnimLayer);
9341 //System.out.println(
9342 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9343 }
9344 }
9345
9346 private boolean mInLayout = false;
9347 private final void performLayoutAndPlaceSurfacesLocked() {
9348 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009349 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350 throw new RuntimeException("Recursive call!");
9351 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009352 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009353 return;
9354 }
9355
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009356 if (mWaitingForConfig) {
9357 // Our configuration has changed (most likely rotation), but we
9358 // don't yet have the complete configuration to report to
9359 // applications. Don't do any window layout until we have it.
9360 return;
9361 }
9362
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009363 if (mDisplay == null) {
9364 // Not yet initialized, nothing to do.
9365 return;
9366 }
9367
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009368 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009370
9371 try {
9372 if (mForceRemoves != null) {
9373 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009374 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009375 for (int i=0; i<mForceRemoves.size(); i++) {
9376 WindowState ws = mForceRemoves.get(i);
9377 Slog.i(TAG, "Force removing: " + ws);
9378 removeWindowInnerLocked(ws.mSession, ws);
9379 }
9380 mForceRemoves = null;
9381 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
9382 Object tmp = new Object();
9383 synchronized (tmp) {
9384 try {
9385 tmp.wait(250);
9386 } catch (InterruptedException e) {
9387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 }
9389 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009390 } catch (RuntimeException e) {
9391 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009392 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 try {
9395 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009396
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009397 int N = mPendingRemove.size();
9398 if (N > 0) {
9399 if (mPendingRemoveTmp.length < N) {
9400 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009402 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009403 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009404 for (int i=0; i<N; i++) {
9405 WindowState w = mPendingRemoveTmp[i];
9406 removeWindowInnerLocked(w.mSession, w);
9407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009408
9409 mInLayout = false;
9410 assignLayersLocked();
9411 mLayoutNeeded = true;
9412 performLayoutAndPlaceSurfacesLocked();
9413
9414 } else {
9415 mInLayout = false;
9416 if (mLayoutNeeded) {
9417 requestAnimationLocked(0);
9418 }
9419 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009420 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009421 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9422 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 } catch (RuntimeException e) {
9425 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009426 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 }
9428 }
9429
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009430 private final int performLayoutLockedInner(boolean initial) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009431 if (!mLayoutNeeded) {
9432 return 0;
9433 }
9434
9435 mLayoutNeeded = false;
9436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 final int dw = mDisplay.getWidth();
9438 final int dh = mDisplay.getHeight();
9439
9440 final int N = mWindows.size();
9441 int i;
9442
Joe Onorato8a9b2202010-02-26 18:56:32 -08009443 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009444 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9445
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009446 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009447
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009448 int seq = mLayoutSeq+1;
9449 if (seq < 0) seq = 0;
9450 mLayoutSeq = seq;
9451
9452 // First perform layout of any root windows (not attached
9453 // to another window).
9454 int topAttached = -1;
9455 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009456 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009457
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009458 // Don't do layout of a window if it is not visible, or
9459 // soon won't be visible, to avoid wasting time and funky
9460 // changes while a window is animating away.
9461 final AppWindowToken atoken = win.mAppToken;
9462 final boolean gone = win.mViewVisibility == View.GONE
9463 || !win.mRelayoutCalled
9464 || win.mRootToken.hidden
9465 || (atoken != null && atoken.hiddenRequested)
9466 || win.mAttachedHidden
9467 || win.mExiting || win.mDestroying;
9468
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009469 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
9470 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009471 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9472 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009473 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009474 + win.mViewVisibility + " mRelayoutCalled="
9475 + win.mRelayoutCalled + " hidden="
9476 + win.mRootToken.hidden + " hiddenRequested="
9477 + (atoken != null && atoken.hiddenRequested)
9478 + " mAttachedHidden=" + win.mAttachedHidden);
9479 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009480
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009481 // If this view is GONE, then skip it -- keep the current
9482 // frame, and let the caller know so they can ignore it
9483 // if they want. (We do the normal layout for INVISIBLE
9484 // windows, since that means "perform layout as normal,
9485 // just don't display").
9486 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009487 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009488 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009489 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009490 win.mContentChanged = false;
9491 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009492 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9493 win.mLayoutSeq = seq;
9494 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9495 + win.mFrame + " mContainingFrame="
9496 + win.mContainingFrame + " mDisplayFrame="
9497 + win.mDisplayFrame);
9498 } else {
9499 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009500 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009502 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009503
9504 // Now perform layout of attached windows, which usually
9505 // depend on the position of the window they are attached to.
9506 // XXX does not deal with windows that are attached to windows
9507 // that are themselves attached.
9508 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009509 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009510
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009511 if (win.mLayoutAttached) {
9512 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9513 + " mHaveFrame=" + win.mHaveFrame
9514 + " mViewVisibility=" + win.mViewVisibility
9515 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009516 // If this view is GONE, then skip it -- keep the current
9517 // frame, and let the caller know so they can ignore it
9518 // if they want. (We do the normal layout for INVISIBLE
9519 // windows, since that means "perform layout as normal,
9520 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009521 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9522 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009523 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009524 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009525 win.mContentChanged = false;
9526 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009527 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9528 win.mLayoutSeq = seq;
9529 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9530 + win.mFrame + " mContainingFrame="
9531 + win.mContainingFrame + " mDisplayFrame="
9532 + win.mDisplayFrame);
9533 }
9534 }
9535 }
Jeff Brown349703e2010-06-22 01:27:15 -07009536
9537 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009538 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009539
9540 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 }
Romain Guy06882f82009-06-10 13:36:04 -07009542
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009543 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009544 private final void performLayoutAndPlaceSurfacesLockedInner(
9545 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009546 if (mDisplay == null) {
9547 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9548 return;
9549 }
9550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009551 final long currentTime = SystemClock.uptimeMillis();
9552 final int dw = mDisplay.getWidth();
9553 final int dh = mDisplay.getHeight();
9554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 int i;
9556
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009557 if (mFocusMayChange) {
9558 mFocusMayChange = false;
9559 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9560 }
9561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009562 // Initialize state of exiting tokens.
9563 for (i=mExitingTokens.size()-1; i>=0; i--) {
9564 mExitingTokens.get(i).hasVisible = false;
9565 }
9566
9567 // Initialize state of exiting applications.
9568 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9569 mExitingAppTokens.get(i).hasVisible = false;
9570 }
9571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009572 boolean orientationChangeComplete = true;
9573 Session holdScreen = null;
9574 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009575 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576 boolean focusDisplayed = false;
9577 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009578 boolean createWatermark = false;
9579
9580 if (mFxSession == null) {
9581 mFxSession = new SurfaceSession();
9582 createWatermark = true;
9583 }
9584
9585 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009586
9587 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009588
9589 if (createWatermark) {
9590 createWatermark();
9591 }
9592 if (mWatermark != null) {
9593 mWatermark.positionSurface(dw, dh);
9594 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009595 if (mStrictModeFlash != null) {
9596 mStrictModeFlash.positionSurface(dw, dh);
9597 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009600 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009601 int repeats = 0;
9602 int changes = 0;
9603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009605 repeats++;
9606 if (repeats > 6) {
9607 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9608 mLayoutNeeded = false;
9609 break;
9610 }
9611
9612 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9613 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9614 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9615 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9616 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9617 assignLayersLocked();
9618 mLayoutNeeded = true;
9619 }
9620 }
9621 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9622 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9623 if (updateOrientationFromAppTokensLocked()) {
9624 mLayoutNeeded = true;
9625 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9626 }
9627 }
9628 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9629 mLayoutNeeded = true;
9630 }
9631 }
9632
9633 // FIRST LOOP: Perform a layout, if needed.
9634 if (repeats < 4) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009635 changes = performLayoutLockedInner(repeats == 0);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009636 if (changes != 0) {
9637 continue;
9638 }
9639 } else {
9640 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9641 changes = 0;
9642 }
9643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 final int transactionSequence = ++mTransactionSequence;
9645
9646 // Update animations of all applications, including those
9647 // associated with exiting/removed apps
9648 boolean tokensAnimating = false;
9649 final int NAT = mAppTokens.size();
9650 for (i=0; i<NAT; i++) {
9651 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9652 tokensAnimating = true;
9653 }
9654 }
9655 final int NEAT = mExitingAppTokens.size();
9656 for (i=0; i<NEAT; i++) {
9657 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9658 tokensAnimating = true;
9659 }
9660 }
9661
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009662 // SECOND LOOP: Execute animations and update visibility of windows.
9663
Joe Onorato8a9b2202010-02-26 18:56:32 -08009664 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009665 + transactionSequence + " tokensAnimating="
9666 + tokensAnimating);
9667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009668 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009669
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009670 if (mScreenRotationAnimation != null) {
9671 if (mScreenRotationAnimation.isAnimating()) {
9672 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
9673 animating = true;
9674 } else {
9675 mScreenRotationAnimation = null;
9676 }
9677 }
9678 }
9679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009680 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009681 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009682 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009683 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684
9685 mPolicy.beginAnimationLw(dw, dh);
9686
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009687 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009689 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009690 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009691
9692 final WindowManager.LayoutParams attrs = w.mAttrs;
9693
9694 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009695 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009696 if (w.commitFinishDrawingLocked(currentTime)) {
9697 if ((w.mAttrs.flags
9698 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009699 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009700 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009701 wallpaperMayChange = true;
9702 }
9703 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009704
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009705 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009706
9707 int animDw = dw;
9708 int animDh = dh;
9709
9710 // If the window has moved due to its containing
9711 // content frame changing, then we'd like to animate
9712 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08009713 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009714 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009715 // Frame has moved, containing content frame
9716 // has also moved, and we're not currently animating...
9717 // let's do something.
9718 Animation a = AnimationUtils.loadAnimation(mContext,
9719 com.android.internal.R.anim.window_move_from_decor);
9720 w.setAnimation(a);
9721 animDw = w.mLastFrame.left - w.mFrame.left;
9722 animDh = w.mLastFrame.top - w.mFrame.top;
9723 }
9724
9725 // Execute animation.
9726 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
9727 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009728
9729 // If this window is animating, make a note that we have
9730 // an animating window and take care of a request to run
9731 // a detached wallpaper animation.
9732 if (nowAnimating) {
9733 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
9734 windowDetachedWallpaper = w;
9735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009737 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009738
9739 // If this window's app token is running a detached wallpaper
9740 // animation, make a note so we can ensure the wallpaper is
9741 // displayed behind it.
9742 if (w.mAppToken != null && w.mAppToken.animation != null
9743 && w.mAppToken.animation.getDetachWallpaper()) {
9744 windowDetachedWallpaper = w;
9745 }
9746
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009747 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9748 wallpaperMayChange = true;
9749 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009750
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009751 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009752 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009753 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009754 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009755 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009756 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009757 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009758 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9759 forceHiding = true;
9760 }
9761 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9762 boolean changed;
9763 if (forceHiding) {
9764 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009765 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9766 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009767 } else {
9768 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009769 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9770 "Now policy shown: " + w);
9771 if (changed) {
9772 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009773 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009774 // Assume we will need to animate. If
9775 // we don't (because the wallpaper will
9776 // stay with the lock screen), then we will
9777 // clean up later.
9778 Animation a = mPolicy.createForceHideEnterAnimation();
9779 if (a != null) {
9780 w.setAnimation(a);
9781 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009782 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009783 if (mCurrentFocus == null ||
9784 mCurrentFocus.mLayer < w.mLayer) {
9785 // We are showing on to of the current
9786 // focus, so re-evaluate focus to make
9787 // sure it is correct.
9788 mFocusMayChange = true;
9789 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009790 }
9791 }
9792 if (changed && (attrs.flags
9793 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9794 wallpaperMayChange = true;
9795 }
9796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 mPolicy.animatingWindowLw(w, attrs);
9799 }
9800
9801 final AppWindowToken atoken = w.mAppToken;
9802 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9803 if (atoken.lastTransactionSequence != transactionSequence) {
9804 atoken.lastTransactionSequence = transactionSequence;
9805 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9806 atoken.startingDisplayed = false;
9807 }
9808 if ((w.isOnScreen() || w.mAttrs.type
9809 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9810 && !w.mExiting && !w.mDestroying) {
9811 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009812 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009813 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009815 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009816 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 + " pv=" + w.mPolicyVisibility
9818 + " dp=" + w.mDrawPending
9819 + " cdp=" + w.mCommitDrawPending
9820 + " ah=" + w.mAttachedHidden
9821 + " th=" + atoken.hiddenRequested
9822 + " a=" + w.mAnimating);
9823 }
9824 }
9825 if (w != atoken.startingWindow) {
9826 if (!atoken.freezingScreen || !w.mAppFreezing) {
9827 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009828 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009829 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009830 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 "tokenMayBeDrawn: " + atoken
9832 + " freezingScreen=" + atoken.freezingScreen
9833 + " mAppFreezing=" + w.mAppFreezing);
9834 tokenMayBeDrawn = true;
9835 }
9836 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009837 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009838 atoken.startingDisplayed = true;
9839 }
9840 }
9841 } else if (w.mReadyToShow) {
9842 w.performShowLocked();
9843 }
9844 }
9845
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009846 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009847
9848 if (tokenMayBeDrawn) {
9849 // See if any windows have been drawn, so they (and others
9850 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009851 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009852 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009853 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 if (wtoken.freezingScreen) {
9855 int numInteresting = wtoken.numInterestingWindows;
9856 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009857 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 "allDrawn: " + wtoken
9859 + " interesting=" + numInteresting
9860 + " drawn=" + wtoken.numDrawnWindows);
9861 wtoken.showAllWindowsLocked();
9862 unsetAppFreezingScreenLocked(wtoken, false, true);
9863 orientationChangeComplete = true;
9864 }
9865 } else if (!wtoken.allDrawn) {
9866 int numInteresting = wtoken.numInterestingWindows;
9867 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009868 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 "allDrawn: " + wtoken
9870 + " interesting=" + numInteresting
9871 + " drawn=" + wtoken.numDrawnWindows);
9872 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009873 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874
9875 // We can now show all of the drawn windows!
9876 if (!mOpeningApps.contains(wtoken)) {
9877 wtoken.showAllWindowsLocked();
9878 }
9879 }
9880 }
9881 }
9882 }
9883
9884 // If we are ready to perform an app transition, check through
9885 // all of the app tokens to be shown and see if they are ready
9886 // to go.
9887 if (mAppTransitionReady) {
9888 int NN = mOpeningApps.size();
9889 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009890 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 "Checking " + NN + " opening apps (frozen="
9892 + mDisplayFrozen + " timeout="
9893 + mAppTransitionTimeout + ")...");
9894 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9895 // If the display isn't frozen, wait to do anything until
9896 // all of the apps are ready. Otherwise just go because
9897 // we'll unfreeze the display when everyone is ready.
9898 for (i=0; i<NN && goodToGo; i++) {
9899 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009900 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 "Check opening app" + wtoken + ": allDrawn="
9902 + wtoken.allDrawn + " startingDisplayed="
9903 + wtoken.startingDisplayed);
9904 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9905 && !wtoken.startingMoved) {
9906 goodToGo = false;
9907 }
9908 }
9909 }
9910 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009911 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 int transit = mNextAppTransition;
9913 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009914 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009916 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009917 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009918 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009919 mAppTransitionTimeout = false;
9920 mStartingIconInTransition = false;
9921 mSkipAppTransitionAnimation = false;
9922
9923 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9924
Dianne Hackborna8f60182009-09-01 19:01:50 -07009925 // If there are applications waiting to come to the
9926 // top of the stack, now is the time to move their windows.
9927 // (Note that we don't do apps going to the bottom
9928 // here -- we want to keep their windows in the old
9929 // Z-order until the animation completes.)
9930 if (mToTopApps.size() > 0) {
9931 NN = mAppTokens.size();
9932 for (i=0; i<NN; i++) {
9933 AppWindowToken wtoken = mAppTokens.get(i);
9934 if (wtoken.sendingToTop) {
9935 wtoken.sendingToTop = false;
9936 moveAppWindowsLocked(wtoken, NN, false);
9937 }
9938 }
9939 mToTopApps.clear();
9940 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009941
Dianne Hackborn25994b42009-09-04 14:21:19 -07009942 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009943
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009944 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009945 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009946
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009947 // The top-most window will supply the layout params,
9948 // and we will determine it below.
9949 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009950 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009951 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009952
Joe Onorato8a9b2202010-02-26 18:56:32 -08009953 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009954 "New wallpaper target=" + mWallpaperTarget
9955 + ", lower target=" + mLowerWallpaperTarget
9956 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009957 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009958 // Do a first pass through the tokens for two
9959 // things:
9960 // (1) Determine if both the closing and opening
9961 // app token sets are wallpaper targets, in which
9962 // case special animations are needed
9963 // (since the wallpaper needs to stay static
9964 // behind them).
9965 // (2) Find the layout params of the top-most
9966 // application window in the tokens, which is
9967 // what will control the animation theme.
9968 final int NC = mClosingApps.size();
9969 NN = NC + mOpeningApps.size();
9970 for (i=0; i<NN; i++) {
9971 AppWindowToken wtoken;
9972 int mode;
9973 if (i < NC) {
9974 wtoken = mClosingApps.get(i);
9975 mode = 1;
9976 } else {
9977 wtoken = mOpeningApps.get(i-NC);
9978 mode = 2;
9979 }
9980 if (mLowerWallpaperTarget != null) {
9981 if (mLowerWallpaperTarget.mAppToken == wtoken
9982 || mUpperWallpaperTarget.mAppToken == wtoken) {
9983 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009984 }
9985 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009986 if (wtoken.appFullscreen) {
9987 WindowState ws = wtoken.findMainWindow();
9988 if (ws != null) {
9989 // If this is a compatibility mode
9990 // window, we will always use its anim.
9991 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9992 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009993 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009994 bestAnimLayer = Integer.MAX_VALUE;
9995 } else if (ws.mLayer > bestAnimLayer) {
9996 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009997 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009998 bestAnimLayer = ws.mLayer;
9999 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010000 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010001 }
10002 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010003
Dianne Hackborn25994b42009-09-04 14:21:19 -070010004 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010005 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010006 "Wallpaper animation!");
10007 switch (transit) {
10008 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10009 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10010 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10011 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10012 break;
10013 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10014 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10015 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10016 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10017 break;
10018 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010019 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010020 "New transit: " + transit);
10021 } else if (oldWallpaper != null) {
10022 // We are transitioning from an activity with
10023 // a wallpaper to one without.
10024 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010025 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010026 "New transit away from wallpaper: " + transit);
10027 } else if (mWallpaperTarget != null) {
10028 // We are transitioning from an activity without
10029 // a wallpaper to now showing the wallpaper
10030 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010031 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010032 "New transit into wallpaper: " + transit);
10033 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010034
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010035 // If all closing windows are obscured, then there is
10036 // no need to do an animation. This is the case, for
10037 // example, when this transition is being done behind
10038 // the lock screen.
10039 if (!mPolicy.allowAppAnimationsLw()) {
10040 animLp = null;
10041 }
10042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 NN = mOpeningApps.size();
10044 for (i=0; i<NN; i++) {
10045 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010046 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010047 "Now opening app" + wtoken);
10048 wtoken.reportedVisible = false;
10049 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010050 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010051 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010053 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 wtoken.showAllWindowsLocked();
10055 }
10056 NN = mClosingApps.size();
10057 for (i=0; i<NN; i++) {
10058 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010059 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010060 "Now closing app" + wtoken);
10061 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010062 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010063 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010064 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010065 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010066 // Force the allDrawn flag, because we want to start
10067 // this guy's animations regardless of whether it's
10068 // gotten drawn.
10069 wtoken.allDrawn = true;
10070 }
10071
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010072 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010074 mOpeningApps.clear();
10075 mClosingApps.clear();
10076
10077 // This has changed the visibility of windows, so perform
10078 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010079 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010081 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10082 assignLayersLocked();
10083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010085 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010086 }
10087 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010088
Dianne Hackborn16064f92010-03-25 00:47:24 -070010089 int adjResult = 0;
10090
Dianne Hackborna8f60182009-09-01 19:01:50 -070010091 if (!animating && mAppTransitionRunning) {
10092 // We have finished the animation of an app transition. To do
10093 // this, we have delayed a lot of operations like showing and
10094 // hiding apps, moving apps in Z-order, etc. The app token list
10095 // reflects the correct Z-order, but the window list may now
10096 // be out of sync with it. So here we will just rebuild the
10097 // entire app window list. Fun!
10098 mAppTransitionRunning = false;
10099 // Clear information about apps that were moving.
10100 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010101
Dianne Hackborna8f60182009-09-01 19:01:50 -070010102 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010103 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010104 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010105 moveInputMethodWindowsIfNeededLocked(false);
10106 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010107 // Since the window list has been rebuilt, focus might
10108 // have to be recomputed since the actual order of windows
10109 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010110 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010111 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010112
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010113 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010114 // At this point, there was a window with a wallpaper that
10115 // was force hiding other windows behind it, but now it
10116 // is going away. This may be simple -- just animate
10117 // away the wallpaper and its window -- or it may be
10118 // hard -- the wallpaper now needs to be shown behind
10119 // something that was hidden.
10120 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010121 if (mLowerWallpaperTarget != null
10122 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010123 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010124 "wallpaperForceHiding changed with lower="
10125 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010126 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010127 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10128 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10129 if (mLowerWallpaperTarget.mAppToken.hidden) {
10130 // The lower target has become hidden before we
10131 // actually started the animation... let's completely
10132 // re-evaluate everything.
10133 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010134 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010135 }
10136 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010137 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010138 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010139 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010140 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010141 + " NEW: " + mWallpaperTarget
10142 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010143 if (mLowerWallpaperTarget == null) {
10144 // Whoops, we don't need a special wallpaper animation.
10145 // Clear them out.
10146 forceHiding = false;
10147 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010148 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010149 if (w.mSurface != null) {
10150 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010151 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010152 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010153 forceHiding = true;
10154 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10155 if (!w.mAnimating) {
10156 // We set the animation above so it
10157 // is not yet running.
10158 w.clearAnimation();
10159 }
10160 }
10161 }
10162 }
10163 }
10164 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010165
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080010166 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
10167 if (DEBUG_WALLPAPER) Slog.v(TAG,
10168 "Detached wallpaper changed from " + mWindowDetachedWallpaper
10169 + windowDetachedWallpaper);
10170 mWindowDetachedWallpaper = windowDetachedWallpaper;
10171 wallpaperMayChange = true;
10172 }
10173
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010174 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010175 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010176 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010177 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010178 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010179
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010180 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010181 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010182 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010183 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010184 assignLayersLocked();
10185 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010186 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010187 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010188 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010189 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010190
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010191 if (mFocusMayChange) {
10192 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010193 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010194 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010195 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010196 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010197 }
10198
10199 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010200 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010201 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010202
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010203 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10204 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010205
Jeff Browne33348b2010-07-15 23:54:05 -070010206 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010207 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208
10209 // THIRD LOOP: Update the surfaces of all windows.
10210
10211 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10212
10213 boolean obscured = false;
10214 boolean blurring = false;
10215 boolean dimming = false;
10216 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010217 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010218 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010220 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010222 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010223 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010224
10225 boolean displayed = false;
10226 final WindowManager.LayoutParams attrs = w.mAttrs;
10227 final int attrFlags = attrs.flags;
10228
10229 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010230 // XXX NOTE: The logic here could be improved. We have
10231 // the decision about whether to resize a window separated
10232 // from whether to hide the surface. This can cause us to
10233 // resize a surface even if we are going to hide it. You
10234 // can see this by (1) holding device in landscape mode on
10235 // home screen; (2) tapping browser icon (device will rotate
10236 // to landscape; (3) tap home. The wallpaper will be resized
10237 // in step 2 but then immediately hidden, causing us to
10238 // have to resize and then redraw it again in step 3. It
10239 // would be nice to figure out how to avoid this, but it is
10240 // difficult because we do need to resize surfaces in some
10241 // cases while they are hidden such as when first showing a
10242 // window.
10243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010245 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010246 TAG, "Placing surface #" + i + " " + w.mSurface
10247 + ": new=" + w.mShownFrame + ", old="
10248 + w.mLastShownFrame);
10249
10250 boolean resize;
10251 int width, height;
10252 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10253 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10254 w.mLastRequestedHeight != w.mRequestedHeight;
10255 // for a scaled surface, we just want to use
10256 // the requested size.
10257 width = w.mRequestedWidth;
10258 height = w.mRequestedHeight;
10259 w.mLastRequestedWidth = width;
10260 w.mLastRequestedHeight = height;
10261 w.mLastShownFrame.set(w.mShownFrame);
10262 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010263 if (SHOW_TRANSACTIONS) logSurface(w,
10264 "POS " + w.mShownFrame.left
10265 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010266 w.mSurfaceX = w.mShownFrame.left;
10267 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10269 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010270 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 if (!recoveringMemory) {
10272 reclaimSomeSurfaceMemoryLocked(w, "position");
10273 }
10274 }
10275 } else {
10276 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10277 width = w.mShownFrame.width();
10278 height = w.mShownFrame.height();
10279 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010280 }
10281
10282 if (resize) {
10283 if (width < 1) width = 1;
10284 if (height < 1) height = 1;
10285 if (w.mSurface != null) {
10286 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010287 if (SHOW_TRANSACTIONS) logSurface(w,
10288 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010289 + w.mShownFrame.top + " SIZE "
10290 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010291 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010292 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010293 w.mSurfaceW = width;
10294 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010296 w.mSurfaceX = w.mShownFrame.left;
10297 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 w.mSurface.setPosition(w.mShownFrame.left,
10299 w.mShownFrame.top);
10300 } catch (RuntimeException e) {
10301 // If something goes wrong with the surface (such
10302 // as running out of memory), don't take down the
10303 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010304 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010305 + "size=(" + width + "x" + height
10306 + "), pos=(" + w.mShownFrame.left
10307 + "," + w.mShownFrame.top + ")", e);
10308 if (!recoveringMemory) {
10309 reclaimSomeSurfaceMemoryLocked(w, "size");
10310 }
10311 }
10312 }
10313 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010314 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010315 w.mContentInsetsChanged =
10316 !w.mLastContentInsets.equals(w.mContentInsets);
10317 w.mVisibleInsetsChanged =
10318 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010319 boolean configChanged =
10320 w.mConfiguration != mCurConfiguration
10321 && (w.mConfiguration == null
10322 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010323 if (DEBUG_CONFIGURATION && configChanged) {
10324 Slog.v(TAG, "Win " + w + " config changed: "
10325 + mCurConfiguration);
10326 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010327 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010328 + ": configChanged=" + configChanged
10329 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010330 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010332 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010333 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010334 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010335 w.mLastFrame.set(w.mFrame);
10336 w.mLastContentInsets.set(w.mContentInsets);
10337 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010338 // If the screen is currently frozen, then keep
10339 // it frozen until this window draws at its new
10340 // orientation.
10341 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010342 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010343 "Resizing while display frozen: " + w);
10344 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010345 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010346 mWindowsFreezingScreen = true;
10347 // XXX should probably keep timeout from
10348 // when we first froze the display.
10349 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10350 mH.sendMessageDelayed(mH.obtainMessage(
10351 H.WINDOW_FREEZE_TIMEOUT), 2000);
10352 }
10353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010354 // If the orientation is changing, then we need to
10355 // hold off on unfreezing the display until this
10356 // window has been redrawn; to do that, we need
10357 // to go through the process of getting informed
10358 // by the application when it has finished drawing.
10359 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010360 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 "Orientation start waiting for draw in "
10362 + w + ", surface " + w.mSurface);
10363 w.mDrawPending = true;
10364 w.mCommitDrawPending = false;
10365 w.mReadyToShow = false;
10366 if (w.mAppToken != null) {
10367 w.mAppToken.allDrawn = false;
10368 }
10369 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010370 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 "Resizing window " + w + " to " + w.mFrame);
10372 mResizingWindows.add(w);
10373 } else if (w.mOrientationChanging) {
10374 if (!w.mDrawPending && !w.mCommitDrawPending) {
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 not waiting for draw in "
10377 + w + ", surface " + w.mSurface);
10378 w.mOrientationChanging = false;
10379 }
10380 }
10381 }
10382
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010383 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 if (!w.mLastHidden) {
10385 //dump();
10386 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010387 if (SHOW_TRANSACTIONS) logSurface(w,
10388 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010389 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010390 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010391 try {
10392 w.mSurface.hide();
10393 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010394 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010395 }
10396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 }
10398 // If we are waiting for this window to handle an
10399 // orientation change, well, it is hidden, so
10400 // doesn't really matter. Note that this does
10401 // introduce a potential glitch if the window
10402 // becomes unhidden before it has drawn for the
10403 // new orientation.
10404 if (w.mOrientationChanging) {
10405 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010406 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010407 "Orientation change skips hidden " + w);
10408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010409 } else if (w.mLastLayer != w.mAnimLayer
10410 || w.mLastAlpha != w.mShownAlpha
10411 || w.mLastDsDx != w.mDsDx
10412 || w.mLastDtDx != w.mDtDx
10413 || w.mLastDsDy != w.mDsDy
10414 || w.mLastDtDy != w.mDtDy
10415 || w.mLastHScale != w.mHScale
10416 || w.mLastVScale != w.mVScale
10417 || w.mLastHidden) {
10418 displayed = true;
10419 w.mLastAlpha = w.mShownAlpha;
10420 w.mLastLayer = w.mAnimLayer;
10421 w.mLastDsDx = w.mDsDx;
10422 w.mLastDtDx = w.mDtDx;
10423 w.mLastDsDy = w.mDsDy;
10424 w.mLastDtDy = w.mDtDy;
10425 w.mLastHScale = w.mHScale;
10426 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010427 if (SHOW_TRANSACTIONS) logSurface(w,
10428 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010429 + " matrix=[" + (w.mDsDx*w.mHScale)
10430 + "," + (w.mDtDx*w.mVScale)
10431 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010432 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010433 if (w.mSurface != null) {
10434 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010435 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010437 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010438 w.mSurface.setLayer(w.mAnimLayer);
10439 w.mSurface.setMatrix(
10440 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10441 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10442 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010444 if (!recoveringMemory) {
10445 reclaimSomeSurfaceMemoryLocked(w, "update");
10446 }
10447 }
10448 }
10449
10450 if (w.mLastHidden && !w.mDrawPending
10451 && !w.mCommitDrawPending
10452 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010453 if (SHOW_TRANSACTIONS) logSurface(w,
10454 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010455 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010456 + " during relayout");
10457 if (showSurfaceRobustlyLocked(w)) {
10458 w.mHasDrawn = true;
10459 w.mLastHidden = false;
10460 } else {
10461 w.mOrientationChanging = false;
10462 }
10463 }
10464 if (w.mSurface != null) {
10465 w.mToken.hasVisible = true;
10466 }
10467 } else {
10468 displayed = true;
10469 }
10470
10471 if (displayed) {
10472 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010473 if (attrs.width == LayoutParams.MATCH_PARENT
10474 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010475 covered = true;
10476 }
10477 }
10478 if (w.mOrientationChanging) {
10479 if (w.mDrawPending || w.mCommitDrawPending) {
10480 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010481 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010482 "Orientation continue waiting for draw in " + w);
10483 } else {
10484 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010485 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486 "Orientation change complete in " + w);
10487 }
10488 }
10489 w.mToken.hasVisible = true;
10490 }
10491 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010492 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010493 "Orientation change skips hidden " + w);
10494 w.mOrientationChanging = false;
10495 }
10496
Dianne Hackborn0f761d62010-11-30 22:06:10 -080010497 if (w.mContentChanged) {
10498 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
10499 w.mContentChanged = false;
10500 }
10501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010502 final boolean canBeSeen = w.isDisplayedLw();
10503
10504 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10505 focusDisplayed = true;
10506 }
10507
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010508 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010510 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010511 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010512 if (w.mSurface != null) {
10513 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10514 holdScreen = w.mSession;
10515 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010516 if (!syswin && w.mAttrs.screenBrightness >= 0
10517 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 screenBrightness = w.mAttrs.screenBrightness;
10519 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010520 if (!syswin && w.mAttrs.buttonBrightness >= 0
10521 && buttonBrightness < 0) {
10522 buttonBrightness = w.mAttrs.buttonBrightness;
10523 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010524 if (canBeSeen
10525 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10526 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10527 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010528 syswin = true;
10529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010531
Dianne Hackborn25994b42009-09-04 14:21:19 -070010532 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10533 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 // This window completely covers everything behind it,
10535 // so we want to leave all of them as unblurred (for
10536 // performance reasons).
10537 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010538 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010539 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010540 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010541 obscured = true;
10542 if (mBackgroundFillerSurface == null) {
10543 try {
10544 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010545 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010546 0, dw, dh,
10547 PixelFormat.OPAQUE,
10548 Surface.FX_SURFACE_NORMAL);
10549 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010550 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010551 }
10552 }
10553 try {
10554 mBackgroundFillerSurface.setPosition(0, 0);
10555 mBackgroundFillerSurface.setSize(dw, dh);
10556 // Using the same layer as Dim because they will never be shown at the
10557 // same time.
10558 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10559 mBackgroundFillerSurface.show();
10560 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010561 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010562 }
10563 backgroundFillerShown = true;
10564 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010565 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010567 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010568 + ": blurring=" + blurring
10569 + " obscured=" + obscured
10570 + " displayed=" + displayed);
10571 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10572 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010573 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010574 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010575 if (mDimAnimator == null) {
10576 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010578 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -080010579 mDimAnimator.updateParameters(mContext.getResources(),
10580 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010582 }
10583 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10584 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010585 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010588 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010589 + mBlurSurface + ": CREATE");
10590 try {
Romain Guy06882f82009-06-10 13:36:04 -070010591 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010592 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010593 -1, 16, 16,
10594 PixelFormat.OPAQUE,
10595 Surface.FX_SURFACE_BLUR);
10596 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010597 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010598 }
10599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010600 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010601 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10602 + mBlurSurface + ": pos=(0,0) (" +
10603 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604 mBlurSurface.setPosition(0, 0);
10605 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010606 mBlurSurface.setLayer(w.mAnimLayer-2);
10607 if (!mBlurShown) {
10608 try {
10609 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10610 + mBlurSurface + ": SHOW");
10611 mBlurSurface.show();
10612 } catch (RuntimeException e) {
10613 Slog.w(TAG, "Failure showing blur surface", e);
10614 }
10615 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010616 }
10617 }
10618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010619 }
10620 }
10621 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010622
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010623 if (obscuredChanged && mWallpaperTarget == w) {
10624 // This is the wallpaper target and its obscured state
10625 // changed... make sure the current wallaper's visibility
10626 // has been updated accordingly.
10627 updateWallpaperVisibilityLocked();
10628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010630
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010631 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10632 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010633 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010634 try {
10635 mBackgroundFillerSurface.hide();
10636 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010637 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010638 }
10639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010641 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010642 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10643 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 }
Romain Guy06882f82009-06-10 13:36:04 -070010645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010647 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010648 + ": HIDE");
10649 try {
10650 mBlurSurface.hide();
10651 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010652 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010653 }
10654 mBlurShown = false;
10655 }
10656
Joe Onorato8a9b2202010-02-26 18:56:32 -080010657 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010658 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010659 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010660 }
10661
Jeff Browne33348b2010-07-15 23:54:05 -070010662 mInputMonitor.updateInputWindowsLw();
10663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010665
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010666 if (mWatermark != null) {
10667 mWatermark.drawIfNeeded();
10668 }
10669
Joe Onorato8a9b2202010-02-26 18:56:32 -080010670 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010671 "With display frozen, orientationChangeComplete="
10672 + orientationChangeComplete);
10673 if (orientationChangeComplete) {
10674 if (mWindowsFreezingScreen) {
10675 mWindowsFreezingScreen = false;
10676 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10677 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010678 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 }
Romain Guy06882f82009-06-10 13:36:04 -070010680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 i = mResizingWindows.size();
10682 if (i > 0) {
10683 do {
10684 i--;
10685 WindowState win = mResizingWindows.get(i);
10686 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010687 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10688 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010689 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010690 boolean configChanged =
10691 win.mConfiguration != mCurConfiguration
10692 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010693 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10694 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10695 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010696 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010697 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010698 + " / " + mCurConfiguration + " / 0x"
10699 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010700 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010701 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 win.mClient.resized(win.mFrame.width(),
10703 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010704 win.mLastVisibleInsets, win.mDrawPending,
10705 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010706 win.mContentInsetsChanged = false;
10707 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010708 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010709 } catch (RemoteException e) {
10710 win.mOrientationChanging = false;
10711 }
10712 } while (i > 0);
10713 mResizingWindows.clear();
10714 }
Romain Guy06882f82009-06-10 13:36:04 -070010715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010716 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010717 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010718 i = mDestroySurface.size();
10719 if (i > 0) {
10720 do {
10721 i--;
10722 WindowState win = mDestroySurface.get(i);
10723 win.mDestroying = false;
10724 if (mInputMethodWindow == win) {
10725 mInputMethodWindow = null;
10726 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010727 if (win == mWallpaperTarget) {
10728 wallpaperDestroyed = true;
10729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010730 win.destroySurfaceLocked();
10731 } while (i > 0);
10732 mDestroySurface.clear();
10733 }
10734
10735 // Time to remove any exiting tokens?
10736 for (i=mExitingTokens.size()-1; i>=0; i--) {
10737 WindowToken token = mExitingTokens.get(i);
10738 if (!token.hasVisible) {
10739 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010740 if (token.windowType == TYPE_WALLPAPER) {
10741 mWallpaperTokens.remove(token);
10742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 }
10744 }
10745
10746 // Time to remove any exiting applications?
10747 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10748 AppWindowToken token = mExitingAppTokens.get(i);
10749 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010750 // Make sure there is no animation running on this token,
10751 // so any windows associated with it will be removed as
10752 // soon as their animations are complete
10753 token.animation = null;
10754 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080010755 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
10756 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 mAppTokens.remove(token);
10758 mExitingAppTokens.remove(i);
10759 }
10760 }
10761
Dianne Hackborna8f60182009-09-01 19:01:50 -070010762 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010763
Dianne Hackborna8f60182009-09-01 19:01:50 -070010764 if (!animating && mAppTransitionRunning) {
10765 // We have finished the animation of an app transition. To do
10766 // this, we have delayed a lot of operations like showing and
10767 // hiding apps, moving apps in Z-order, etc. The app token list
10768 // reflects the correct Z-order, but the window list may now
10769 // be out of sync with it. So here we will just rebuild the
10770 // entire app window list. Fun!
10771 mAppTransitionRunning = false;
10772 needRelayout = true;
10773 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010774 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010775 // Clear information about apps that were moving.
10776 mToBottomApps.clear();
10777 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 if (focusDisplayed) {
10780 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10781 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010782 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010783 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010784 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010785 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010786 requestAnimationLocked(0);
10787 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010788 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10789 }
Jeff Browneb857f12010-07-16 10:06:33 -070010790
Jeff Browne33348b2010-07-15 23:54:05 -070010791 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010792
Jeff Brown8e03b752010-06-13 19:16:55 -070010793 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010794 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10795 mPowerManager.setScreenBrightnessOverride(-1);
10796 } else {
10797 mPowerManager.setScreenBrightnessOverride((int)
10798 (screenBrightness * Power.BRIGHTNESS_ON));
10799 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010800 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10801 mPowerManager.setButtonBrightnessOverride(-1);
10802 } else {
10803 mPowerManager.setButtonBrightnessOverride((int)
10804 (buttonBrightness * Power.BRIGHTNESS_ON));
10805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 if (holdScreen != mHoldingScreenOn) {
10807 mHoldingScreenOn = holdScreen;
10808 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10809 mH.sendMessage(m);
10810 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010811
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010812 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010813 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010814 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10815 LocalPowerManager.BUTTON_EVENT, true);
10816 mTurnOnScreen = false;
10817 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010818
10819 // Check to see if we are now in a state where the screen should
10820 // be enabled, because the window obscured flags have changed.
10821 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010823
10824 /**
10825 * Must be called with the main window manager lock held.
10826 */
10827 void setHoldScreenLocked(boolean holding) {
10828 boolean state = mHoldingScreenWakeLock.isHeld();
10829 if (holding != state) {
10830 if (holding) {
10831 mHoldingScreenWakeLock.acquire();
10832 } else {
10833 mPolicy.screenOnStoppedLw();
10834 mHoldingScreenWakeLock.release();
10835 }
10836 }
10837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010838
10839 void requestAnimationLocked(long delay) {
10840 if (!mAnimationPending) {
10841 mAnimationPending = true;
10842 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10843 }
10844 }
Romain Guy06882f82009-06-10 13:36:04 -070010845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010846 /**
10847 * Have the surface flinger show a surface, robustly dealing with
10848 * error conditions. In particular, if there is not enough memory
10849 * to show the surface, then we will try to get rid of other surfaces
10850 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010851 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010852 * @return Returns true if the surface was successfully shown.
10853 */
10854 boolean showSurfaceRobustlyLocked(WindowState win) {
10855 try {
10856 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010857 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010858 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010859 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010860 if (DEBUG_VISIBILITY) Slog.v(TAG,
10861 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010862 win.mTurnOnScreen = false;
10863 mTurnOnScreen = true;
10864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010865 }
10866 return true;
10867 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010868 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010869 }
Romain Guy06882f82009-06-10 13:36:04 -070010870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010872
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 return false;
10874 }
Romain Guy06882f82009-06-10 13:36:04 -070010875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010876 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10877 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010878
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010879 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010882 if (mForceRemoves == null) {
10883 mForceRemoves = new ArrayList<WindowState>();
10884 }
Romain Guy06882f82009-06-10 13:36:04 -070010885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010886 long callingIdentity = Binder.clearCallingIdentity();
10887 try {
10888 // There was some problem... first, do a sanity check of the
10889 // window list to make sure we haven't left any dangling surfaces
10890 // around.
10891 int N = mWindows.size();
10892 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010893 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010894 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010895 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 if (ws.mSurface != null) {
10897 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010898 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 + ws + " surface=" + ws.mSurface
10900 + " token=" + win.mToken
10901 + " pid=" + ws.mSession.mPid
10902 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010903 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010904 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 ws.mSurface = null;
10906 mForceRemoves.add(ws);
10907 i--;
10908 N--;
10909 leakedSurface = true;
10910 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010911 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 + ws + " surface=" + ws.mSurface
10913 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010914 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010915 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010916 ws.mSurface = null;
10917 leakedSurface = true;
10918 }
10919 }
10920 }
Romain Guy06882f82009-06-10 13:36:04 -070010921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010922 boolean killedApps = false;
10923 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010924 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 SparseIntArray pidCandidates = new SparseIntArray();
10926 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010927 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010928 if (ws.mSurface != null) {
10929 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10930 }
10931 }
10932 if (pidCandidates.size() > 0) {
10933 int[] pids = new int[pidCandidates.size()];
10934 for (int i=0; i<pids.length; i++) {
10935 pids[i] = pidCandidates.keyAt(i);
10936 }
10937 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010938 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 killedApps = true;
10940 }
10941 } catch (RemoteException e) {
10942 }
10943 }
10944 }
Romain Guy06882f82009-06-10 13:36:04 -070010945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 if (leakedSurface || killedApps) {
10947 // We managed to reclaim some memory, so get rid of the trouble
10948 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010949 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010951 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010952 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010953 win.mSurface = null;
10954 }
Romain Guy06882f82009-06-10 13:36:04 -070010955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010956 try {
10957 win.mClient.dispatchGetNewSurface();
10958 } catch (RemoteException e) {
10959 }
10960 }
10961 } finally {
10962 Binder.restoreCallingIdentity(callingIdentity);
10963 }
10964 }
Romain Guy06882f82009-06-10 13:36:04 -070010965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 private boolean updateFocusedWindowLocked(int mode) {
10967 WindowState newFocus = computeFocusedWindowLocked();
10968 if (mCurrentFocus != newFocus) {
10969 // This check makes sure that we don't already have the focus
10970 // change message pending.
10971 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10972 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010973 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10975 final WindowState oldFocus = mCurrentFocus;
10976 mCurrentFocus = newFocus;
10977 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 final WindowState imWindow = mInputMethodWindow;
10980 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010981 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010983 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10984 mLayoutNeeded = true;
10985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -080010987 performLayoutLockedInner(true);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010988 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10989 // Client will do the layout, but we need to assign layers
10990 // for handleNewWindowLocked() below.
10991 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 }
10993 }
Jeff Brown349703e2010-06-22 01:27:15 -070010994
10995 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10996 // If we defer assigning layers, then the caller is responsible for
10997 // doing this part.
10998 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011000 return true;
11001 }
11002 return false;
11003 }
Jeff Brown349703e2010-06-22 01:27:15 -070011004
11005 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011006 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070011007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011008
11009 private WindowState computeFocusedWindowLocked() {
11010 WindowState result = null;
11011 WindowState win;
11012
11013 int i = mWindows.size() - 1;
11014 int nextAppIndex = mAppTokens.size()-1;
11015 WindowToken nextApp = nextAppIndex >= 0
11016 ? mAppTokens.get(nextAppIndex) : null;
11017
11018 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070011019 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020
Joe Onorato8a9b2202010-02-26 18:56:32 -080011021 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011022 TAG, "Looking for focus: " + i
11023 + " = " + win
11024 + ", flags=" + win.mAttrs.flags
11025 + ", canReceive=" + win.canReceiveKeys());
11026
11027 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 // If this window's application has been removed, just skip it.
11030 if (thisApp != null && thisApp.removed) {
11031 i--;
11032 continue;
11033 }
Romain Guy06882f82009-06-10 13:36:04 -070011034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 // If there is a focused app, don't allow focus to go to any
11036 // windows below it. If this is an application window, step
11037 // through the app tokens until we find its app.
11038 if (thisApp != null && nextApp != null && thisApp != nextApp
11039 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11040 int origAppIndex = nextAppIndex;
11041 while (nextAppIndex > 0) {
11042 if (nextApp == mFocusedApp) {
11043 // Whoops, we are below the focused app... no focus
11044 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011045 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 TAG, "Reached focused app: " + mFocusedApp);
11047 return null;
11048 }
11049 nextAppIndex--;
11050 nextApp = mAppTokens.get(nextAppIndex);
11051 if (nextApp == thisApp) {
11052 break;
11053 }
11054 }
11055 if (thisApp != nextApp) {
11056 // Uh oh, the app token doesn't exist! This shouldn't
11057 // happen, but if it does we can get totally hosed...
11058 // so restart at the original app.
11059 nextAppIndex = origAppIndex;
11060 nextApp = mAppTokens.get(nextAppIndex);
11061 }
11062 }
11063
11064 // Dispatch to this window if it is wants key events.
11065 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011066 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 TAG, "Found focus @ " + i + " = " + win);
11068 result = win;
11069 break;
11070 }
11071
11072 i--;
11073 }
11074
11075 return result;
11076 }
11077
11078 private void startFreezingDisplayLocked() {
11079 if (mDisplayFrozen) {
11080 return;
11081 }
Romain Guy06882f82009-06-10 13:36:04 -070011082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011083 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011085 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011086 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011087 if (mFreezeGcPending != 0) {
11088 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011089 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090 mH.removeMessages(H.FORCE_GC);
11091 Runtime.getRuntime().gc();
11092 mFreezeGcPending = now;
11093 }
11094 } else {
11095 mFreezeGcPending = now;
11096 }
Romain Guy06882f82009-06-10 13:36:04 -070011097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011098 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070011099
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011100 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070011101
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011102 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11103 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011104 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011105 mAppTransitionReady = true;
11106 }
Romain Guy06882f82009-06-10 13:36:04 -070011107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 if (PROFILE_ORIENTATION) {
11109 File file = new File("/data/system/frozen");
11110 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11111 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011112
11113 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011114 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
11115 mScreenRotationAnimation.kill();
11116 mScreenRotationAnimation = null;
11117 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011118 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011119 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
11120 mDisplay, mFxSession);
Dianne Hackborna1111872010-11-23 20:55:11 -080011121 }
11122 } else {
11123 Surface.freezeDisplay(0);
11124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011125 }
Romain Guy06882f82009-06-10 13:36:04 -070011126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011127 private void stopFreezingDisplayLocked() {
11128 if (!mDisplayFrozen) {
11129 return;
11130 }
Romain Guy06882f82009-06-10 13:36:04 -070011131
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011132 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11133 return;
11134 }
11135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 mDisplayFrozen = false;
11137 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11138 if (PROFILE_ORIENTATION) {
11139 Debug.stopMethodTracing();
11140 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011141
11142 if (CUSTOM_SCREEN_ROTATION) {
11143 if (mScreenRotationAnimation != null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011144 if (mScreenRotationAnimation.dismiss(MAX_ANIMATION_DURATION,
11145 mTransitionAnimationScale)) {
11146 requestAnimationLocked(0);
11147 } else {
11148 mScreenRotationAnimation = null;
11149 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011150 }
11151 } else {
11152 Surface.unfreezeDisplay(0);
11153 }
Romain Guy06882f82009-06-10 13:36:04 -070011154
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011155 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011156
Christopher Tateb696aee2010-04-02 19:08:30 -070011157 // While the display is frozen we don't re-compute the orientation
11158 // to avoid inconsistent states. However, something interesting
11159 // could have actually changed during that time so re-evaluate it
11160 // now to catch that.
11161 if (updateOrientationFromAppTokensLocked()) {
11162 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11163 }
11164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 // A little kludge: a lot could have happened while the
11166 // display was frozen, so now that we are coming back we
11167 // do a gc so that any remote references the system
11168 // processes holds on others can be released if they are
11169 // no longer needed.
11170 mH.removeMessages(H.FORCE_GC);
11171 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11172 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011174 mScreenFrozenLock.release();
11175 }
Romain Guy06882f82009-06-10 13:36:04 -070011176
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011177 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
11178 DisplayMetrics dm) {
11179 if (index < tokens.length) {
11180 String str = tokens[index];
11181 if (str != null && str.length() > 0) {
11182 try {
11183 int val = Integer.parseInt(str);
11184 return val;
11185 } catch (Exception e) {
11186 }
11187 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011188 }
11189 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
11190 return defDps;
11191 }
11192 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
11193 return val;
11194 }
11195
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011196 static class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011197 final String[] mTokens;
11198 final String mText;
11199 final Paint mTextPaint;
11200 final int mTextWidth;
11201 final int mTextHeight;
11202 final int mTextAscent;
11203 final int mTextDescent;
11204 final int mDeltaX;
11205 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011206
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011207 Surface mSurface;
11208 int mLastDW;
11209 int mLastDH;
11210 boolean mDrawNeeded;
11211
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011212 Watermark(Display display, SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011213 final DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011214 display.getMetrics(dm);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011215
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011216 if (false) {
11217 Log.i(TAG, "*********************** WATERMARK");
11218 for (int i=0; i<tokens.length; i++) {
11219 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
11220 }
11221 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011222
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011223 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011224
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011225 StringBuilder builder = new StringBuilder(32);
11226 int len = mTokens[0].length();
11227 len = len & ~1;
11228 for (int i=0; i<len; i+=2) {
11229 int c1 = mTokens[0].charAt(i);
11230 int c2 = mTokens[0].charAt(i+1);
11231 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
11232 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
11233 else c1 -= '0';
11234 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
11235 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
11236 else c2 -= '0';
11237 builder.append((char)(255-((c1*16)+c2)));
11238 }
11239 mText = builder.toString();
11240 if (false) {
11241 Log.i(TAG, "Final text: " + mText);
11242 }
11243
11244 int fontSize = getPropertyInt(tokens, 1,
11245 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
11246
11247 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
11248 mTextPaint.setTextSize(fontSize);
11249 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
11250
11251 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
11252 mTextWidth = (int)mTextPaint.measureText(mText);
11253 mTextAscent = fm.ascent;
11254 mTextDescent = fm.descent;
11255 mTextHeight = fm.descent - fm.ascent;
11256
11257 mDeltaX = getPropertyInt(tokens, 2,
11258 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
11259 mDeltaY = getPropertyInt(tokens, 3,
11260 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
11261 int shadowColor = getPropertyInt(tokens, 4,
11262 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
11263 int color = getPropertyInt(tokens, 5,
11264 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
11265 int shadowRadius = getPropertyInt(tokens, 6,
11266 TypedValue.COMPLEX_UNIT_PX, 7, dm);
11267 int shadowDx = getPropertyInt(tokens, 8,
11268 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11269 int shadowDy = getPropertyInt(tokens, 9,
11270 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11271
11272 mTextPaint.setColor(color);
11273 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011274
11275 try {
11276 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011277 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011278 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011279 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011280 mSurface.show();
11281 } catch (OutOfResourcesException e) {
11282 }
11283 }
11284
11285 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011286 if (mLastDW != dw || mLastDH != dh) {
11287 mLastDW = dw;
11288 mLastDH = dh;
11289 mSurface.setSize(dw, dh);
11290 mDrawNeeded = true;
11291 }
11292 }
11293
11294 void drawIfNeeded() {
11295 if (mDrawNeeded) {
11296 final int dw = mLastDW;
11297 final int dh = mLastDH;
11298
11299 mDrawNeeded = false;
11300 Rect dirty = new Rect(0, 0, dw, dh);
11301 Canvas c = null;
11302 try {
11303 c = mSurface.lockCanvas(dirty);
11304 } catch (IllegalArgumentException e) {
11305 } catch (OutOfResourcesException e) {
11306 }
11307 if (c != null) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011308 c.drawColor(0, PorterDuff.Mode.CLEAR);
11309
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011310 int deltaX = mDeltaX;
11311 int deltaY = mDeltaY;
11312
11313 // deltaX shouldn't be close to a round fraction of our
11314 // x step, or else things will line up too much.
11315 int div = (dw+mTextWidth)/deltaX;
11316 int rem = (dw+mTextWidth) - (div*deltaX);
11317 int qdelta = deltaX/4;
11318 if (rem < qdelta || rem > (deltaX-qdelta)) {
11319 deltaX += deltaX/3;
11320 }
11321
11322 int y = -mTextHeight;
11323 int x = -mTextWidth;
11324 while (y < (dh+mTextHeight)) {
11325 c.drawText(mText, x, y, mTextPaint);
11326 x += deltaX;
11327 if (x >= dw) {
11328 x -= (dw+mTextWidth);
11329 y += deltaY;
11330 }
11331 }
11332 mSurface.unlockCanvasAndPost(c);
11333 }
11334 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011335 }
11336 }
11337
11338 void createWatermark() {
11339 if (mWatermark != null) {
11340 return;
11341 }
11342
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011343 File file = new File("/system/etc/setup.conf");
11344 FileInputStream in = null;
11345 try {
11346 in = new FileInputStream(file);
11347 DataInputStream ind = new DataInputStream(in);
11348 String line = ind.readLine();
11349 if (line != null) {
11350 String[] toks = line.split("%");
11351 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011352 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011353 }
11354 }
11355 } catch (FileNotFoundException e) {
11356 } catch (IOException e) {
11357 } finally {
11358 if (in != null) {
11359 try {
11360 in.close();
11361 } catch (IOException e) {
11362 }
11363 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011364 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011365 }
11366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011367 @Override
11368 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11369 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11370 != PackageManager.PERMISSION_GRANTED) {
11371 pw.println("Permission Denial: can't dump WindowManager from from pid="
11372 + Binder.getCallingPid()
11373 + ", uid=" + Binder.getCallingUid());
11374 return;
11375 }
Romain Guy06882f82009-06-10 13:36:04 -070011376
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011377 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080011378 pw.println(" ");
11379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011380 synchronized(mWindowMap) {
11381 pw.println("Current Window Manager state:");
11382 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070011383 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011384 pw.print(" Window #"); pw.print(i); pw.print(' ');
11385 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011386 w.dump(pw, " ");
11387 }
11388 if (mInputMethodDialogs.size() > 0) {
11389 pw.println(" ");
11390 pw.println(" Input method dialogs:");
11391 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11392 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011393 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011394 }
11395 }
11396 if (mPendingRemove.size() > 0) {
11397 pw.println(" ");
11398 pw.println(" Remove pending for:");
11399 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11400 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011401 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11402 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011403 w.dump(pw, " ");
11404 }
11405 }
11406 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11407 pw.println(" ");
11408 pw.println(" Windows force removing:");
11409 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11410 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011411 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11412 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011413 w.dump(pw, " ");
11414 }
11415 }
11416 if (mDestroySurface.size() > 0) {
11417 pw.println(" ");
11418 pw.println(" Windows waiting to destroy their surface:");
11419 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11420 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011421 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11422 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 w.dump(pw, " ");
11424 }
11425 }
11426 if (mLosingFocus.size() > 0) {
11427 pw.println(" ");
11428 pw.println(" Windows losing focus:");
11429 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11430 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011431 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11432 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011433 w.dump(pw, " ");
11434 }
11435 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011436 if (mResizingWindows.size() > 0) {
11437 pw.println(" ");
11438 pw.println(" Windows waiting to resize:");
11439 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11440 WindowState w = mResizingWindows.get(i);
11441 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11442 pw.print(w); pw.println(":");
11443 w.dump(pw, " ");
11444 }
11445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011446 if (mSessions.size() > 0) {
11447 pw.println(" ");
11448 pw.println(" All active sessions:");
11449 Iterator<Session> it = mSessions.iterator();
11450 while (it.hasNext()) {
11451 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011452 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 s.dump(pw, " ");
11454 }
11455 }
11456 if (mTokenMap.size() > 0) {
11457 pw.println(" ");
11458 pw.println(" All tokens:");
11459 Iterator<WindowToken> it = mTokenMap.values().iterator();
11460 while (it.hasNext()) {
11461 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011462 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011463 token.dump(pw, " ");
11464 }
11465 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011466 if (mWallpaperTokens.size() > 0) {
11467 pw.println(" ");
11468 pw.println(" Wallpaper tokens:");
11469 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11470 WindowToken token = mWallpaperTokens.get(i);
11471 pw.print(" Wallpaper #"); pw.print(i);
11472 pw.print(' '); pw.print(token); pw.println(':');
11473 token.dump(pw, " ");
11474 }
11475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011476 if (mAppTokens.size() > 0) {
11477 pw.println(" ");
11478 pw.println(" Application tokens in Z order:");
11479 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011480 pw.print(" App #"); pw.print(i); pw.print(": ");
11481 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011482 }
11483 }
11484 if (mFinishedStarting.size() > 0) {
11485 pw.println(" ");
11486 pw.println(" Finishing start of application tokens:");
11487 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11488 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011489 pw.print(" Finished Starting #"); pw.print(i);
11490 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011491 token.dump(pw, " ");
11492 }
11493 }
11494 if (mExitingTokens.size() > 0) {
11495 pw.println(" ");
11496 pw.println(" Exiting tokens:");
11497 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11498 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011499 pw.print(" Exiting #"); pw.print(i);
11500 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011501 token.dump(pw, " ");
11502 }
11503 }
11504 if (mExitingAppTokens.size() > 0) {
11505 pw.println(" ");
11506 pw.println(" Exiting application tokens:");
11507 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11508 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011509 pw.print(" Exiting App #"); pw.print(i);
11510 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011511 token.dump(pw, " ");
11512 }
11513 }
11514 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011515 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11516 pw.print(" mLastFocus="); pw.println(mLastFocus);
11517 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11518 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11519 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011520 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011521 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11522 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11523 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11524 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080011525 if (mWindowDetachedWallpaper != null) {
11526 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
11527 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011528 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11529 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11530 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011531 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11532 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11533 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11534 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011535 if (mDimAnimator != null) {
11536 mDimAnimator.printTo(pw);
11537 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011538 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011539 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011540 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011541 pw.print(mInputMethodAnimLayerAdjustment);
11542 pw.print(" mWallpaperAnimLayerAdjustment=");
11543 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011544 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11545 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011546 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11547 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011548 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11549 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011550 pw.print(" mRotation="); pw.print(mRotation);
11551 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11552 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11553 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11554 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11555 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11556 pw.print(" mNextAppTransition=0x");
11557 pw.print(Integer.toHexString(mNextAppTransition));
11558 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011559 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011560 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011561 if (mNextAppTransitionPackage != null) {
11562 pw.print(" mNextAppTransitionPackage=");
11563 pw.print(mNextAppTransitionPackage);
11564 pw.print(", mNextAppTransitionEnter=0x");
11565 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11566 pw.print(", mNextAppTransitionExit=0x");
11567 pw.print(Integer.toHexString(mNextAppTransitionExit));
11568 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011569 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11570 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
11571 if (mOpeningApps.size() > 0) {
11572 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11573 }
11574 if (mClosingApps.size() > 0) {
11575 pw.print(" mClosingApps="); pw.println(mClosingApps);
11576 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011577 if (mToTopApps.size() > 0) {
11578 pw.print(" mToTopApps="); pw.println(mToTopApps);
11579 }
11580 if (mToBottomApps.size() > 0) {
11581 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11582 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -080011583 if (mDisplay != null) {
11584 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11585 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
11586 } else {
11587 pw.println(" NO DISPLAY");
11588 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080011589 pw.println(" Policy:");
11590 mPolicy.dump(" ", fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011591 }
11592 }
11593
Jeff Brown349703e2010-06-22 01:27:15 -070011594 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011595 public void monitor() {
11596 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011597 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011599
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011600 /**
11601 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011602 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011603 */
11604 private static class DimAnimator {
11605 Surface mDimSurface;
11606 boolean mDimShown = false;
11607 float mDimCurrentAlpha;
11608 float mDimTargetAlpha;
11609 float mDimDeltaPerMs;
11610 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011611
11612 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011613
11614 DimAnimator (SurfaceSession session) {
11615 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011616 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011617 + mDimSurface + ": CREATE");
11618 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011619 mDimSurface = new Surface(session, 0,
11620 "DimSurface",
11621 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011622 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011623 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011624 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011625 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011626 }
11627 }
11628 }
11629
11630 /**
11631 * Show the dim surface.
11632 */
11633 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011634 if (!mDimShown) {
11635 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11636 dw + "x" + dh + ")");
11637 mDimShown = true;
11638 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011639 mLastDimWidth = dw;
11640 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011641 mDimSurface.setPosition(0, 0);
11642 mDimSurface.setSize(dw, dh);
11643 mDimSurface.show();
11644 } catch (RuntimeException e) {
11645 Slog.w(TAG, "Failure showing dim surface", e);
11646 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011647 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11648 mLastDimWidth = dw;
11649 mLastDimHeight = dh;
11650 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011651 }
11652 }
11653
11654 /**
11655 * Set's the dim surface's layer and update dim parameters that will be used in
11656 * {@link updateSurface} after all windows are examined.
11657 */
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011658 void updateParameters(Resources res, WindowState w, long currentTime) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011659 mDimSurface.setLayer(w.mAnimLayer-1);
11660
11661 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011662 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011663 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011664 if (mDimTargetAlpha != target) {
11665 // If the desired dim level has changed, then
11666 // start an animation to it.
11667 mLastDimAnimTime = currentTime;
11668 long duration = (w.mAnimating && w.mAnimation != null)
11669 ? w.mAnimation.computeDurationHint()
11670 : DEFAULT_DIM_DURATION;
11671 if (target > mDimTargetAlpha) {
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011672 TypedValue tv = new TypedValue();
11673 res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
11674 tv, true);
11675 if (tv.type == TypedValue.TYPE_FRACTION) {
11676 duration = (long)tv.getFraction((float)duration, (float)duration);
11677 } else if (tv.type >= TypedValue.TYPE_FIRST_INT
11678 && tv.type <= TypedValue.TYPE_LAST_INT) {
11679 duration = tv.data;
11680 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011681 }
11682 if (duration < 1) {
11683 // Don't divide by zero
11684 duration = 1;
11685 }
11686 mDimTargetAlpha = target;
11687 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11688 }
11689 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011690
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011691 /**
11692 * Updating the surface's alpha. Returns true if the animation continues, or returns
11693 * false when the animation is finished and the dim surface is hidden.
11694 */
11695 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11696 if (!dimming) {
11697 if (mDimTargetAlpha != 0) {
11698 mLastDimAnimTime = currentTime;
11699 mDimTargetAlpha = 0;
11700 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11701 }
11702 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011703
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011704 boolean animating = false;
11705 if (mLastDimAnimTime != 0) {
11706 mDimCurrentAlpha += mDimDeltaPerMs
11707 * (currentTime-mLastDimAnimTime);
11708 boolean more = true;
11709 if (displayFrozen) {
11710 // If the display is frozen, there is no reason to animate.
11711 more = false;
11712 } else if (mDimDeltaPerMs > 0) {
11713 if (mDimCurrentAlpha > mDimTargetAlpha) {
11714 more = false;
11715 }
11716 } else if (mDimDeltaPerMs < 0) {
11717 if (mDimCurrentAlpha < mDimTargetAlpha) {
11718 more = false;
11719 }
11720 } else {
11721 more = false;
11722 }
11723
11724 // Do we need to continue animating?
11725 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011726 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011727 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11728 mLastDimAnimTime = currentTime;
11729 mDimSurface.setAlpha(mDimCurrentAlpha);
11730 animating = true;
11731 } else {
11732 mDimCurrentAlpha = mDimTargetAlpha;
11733 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011734 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011735 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11736 mDimSurface.setAlpha(mDimCurrentAlpha);
11737 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011738 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011739 + ": HIDE");
11740 try {
11741 mDimSurface.hide();
11742 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011743 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011744 }
11745 mDimShown = false;
11746 }
11747 }
11748 }
11749 return animating;
11750 }
11751
11752 public void printTo(PrintWriter pw) {
11753 pw.print(" mDimShown="); pw.print(mDimShown);
11754 pw.print(" current="); pw.print(mDimCurrentAlpha);
11755 pw.print(" target="); pw.print(mDimTargetAlpha);
11756 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11757 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11758 }
11759 }
11760
11761 /**
11762 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11763 * This is used for opening/closing transition for apps in compatible mode.
11764 */
11765 private static class FadeInOutAnimation extends Animation {
11766 int mWidth;
11767 boolean mFadeIn;
11768
11769 public FadeInOutAnimation(boolean fadeIn) {
11770 setInterpolator(new AccelerateInterpolator());
11771 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11772 mFadeIn = fadeIn;
11773 }
11774
11775 @Override
11776 protected void applyTransformation(float interpolatedTime, Transformation t) {
11777 float x = interpolatedTime;
11778 if (!mFadeIn) {
11779 x = 1.0f - x; // reverse the interpolation for fade out
11780 }
11781 if (x < 0.5) {
11782 // move the window out of the screen.
11783 t.getMatrix().setTranslate(mWidth, 0);
11784 } else {
11785 t.getMatrix().setTranslate(0, 0);// show
11786 t.setAlpha((x - 0.5f) * 2);
11787 }
11788 }
11789
11790 @Override
11791 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11792 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11793 mWidth = width;
11794 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011795
11796 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011797 public int getZAdjustment() {
11798 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011799 }
11800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011801}