blob: 182e898225dc86697d4a4e94fbf6564664623b43 [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 Brown349703e2010-06-22 01:27:15 -0700215
216 // Default input dispatching timeout in nanoseconds.
217 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 static final int UPDATE_FOCUS_NORMAL = 0;
220 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
221 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
222 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700225 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226
227 /**
228 * Condition waited on by {@link #reenableKeyguard} to know the call to
229 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500230 * This is set to true only if mKeyguardTokenWatcher.acquired() has
231 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500233 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234
Jim Miller284b62e2010-06-08 14:27:42 -0700235 private static final int ALLOW_DISABLE_YES = 1;
236 private static final int ALLOW_DISABLE_NO = 0;
237 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
238 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
239
Mike Lockwood983ee092009-11-22 01:42:24 -0500240 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
241 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700243 if (shouldAllowDisableKeyguard()) {
244 mPolicy.enableKeyguard(false);
245 mKeyguardDisabled = true;
246 } else {
247 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 }
250 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700251 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500252 synchronized (mKeyguardTokenWatcher) {
253 mKeyguardDisabled = false;
254 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 }
256 }
257 };
258
Jim Miller284b62e2010-06-08 14:27:42 -0700259 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
260 @Override
261 public void onReceive(Context context, Intent intent) {
262 mPolicy.enableKeyguard(true);
263 synchronized(mKeyguardTokenWatcher) {
264 // lazily evaluate this next time we're asked to disable keyguard
265 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
266 mKeyguardDisabled = false;
267 }
268 }
269 };
270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 final Context mContext;
272
273 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
278
279 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 /**
284 * All currently active sessions with clients.
285 */
286 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 /**
289 * Mapping from an IWindow IBinder to the server's Window object.
290 * This is also used as the lock for all of our state.
291 */
292 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
293
294 /**
295 * Mapping from a token IBinder to a WindowToken object.
296 */
297 final HashMap<IBinder, WindowToken> mTokenMap =
298 new HashMap<IBinder, WindowToken>();
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Window tokens that are in the process of exiting, but still
302 * on screen for animations.
303 */
304 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
305
306 /**
307 * Z-ordered (bottom-most first) list of all application tokens, for
308 * controlling the ordering of windows in different applications. This
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800309 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 */
311 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
312
313 /**
314 * Application tokens that are in the process of exiting, but still
315 * on screen for animations.
316 */
317 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
318
319 /**
320 * List of window tokens that have finished starting their application,
321 * and now need to have the policy remove their windows.
322 */
323 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
324
325 /**
326 * Z-ordered (bottom-most first) list of all Window objects.
327 */
Jeff Browne33348b2010-07-15 23:54:05 -0700328 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329
330 /**
331 * Windows that are being resized. Used so we can tell the client about
332 * the resize after closing the transaction in which we resized the
333 * underlying surface.
334 */
335 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
336
337 /**
338 * Windows whose animations have ended and now must be removed.
339 */
340 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
341
342 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800343 * Used when processing mPendingRemove to avoid working on the original array.
344 */
345 WindowState[] mPendingRemoveTmp = new WindowState[20];
346
347 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 * Windows whose surface should be destroyed.
349 */
350 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
351
352 /**
353 * Windows that have lost input focus and are waiting for the new
354 * focus window to be displayed before they are told about this.
355 */
356 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
357
358 /**
359 * This is set when we have run out of memory, and will either be an empty
360 * list or contain windows that need to be force removed.
361 */
362 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700363
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800364 /**
365 * Used when rebuilding window list to keep track of windows that have
366 * been removed.
367 */
368 WindowState[] mRebuildTmp = new WindowState[20];
369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700373 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 Surface mBlurSurface;
375 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700376 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800377 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800378 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 final float[] mTmpFloats = new float[9];
383
384 boolean mSafeMode;
385 boolean mDisplayEnabled = false;
386 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700387 int mInitialDisplayWidth = 0;
388 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 int mRotation = 0;
390 int mRequestedRotation = 0;
391 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700392 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 ArrayList<IRotationWatcher> mRotationWatchers
394 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 boolean mLayoutNeeded = true;
397 boolean mAnimationPending = false;
398 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800399 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 boolean mWindowsFreezingScreen = false;
401 long mFreezeGcPending = 0;
402 int mAppsFreezingScreen = 0;
403
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800404 int mLayoutSeq = 0;
405
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800406 // State while inside of layoutAndPlaceSurfacesLocked().
407 boolean mFocusMayChange;
408
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800409 Configuration mCurConfiguration = new Configuration();
410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 // This is held as long as we have the screen frozen, to give us time to
412 // perform a rotation animation when turning off shows the lock screen which
413 // changes the orientation.
414 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 // State management of app transitions. When we are preparing for a
417 // transition, mNextAppTransition will be the kind of transition to
418 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
419 // mOpeningApps and mClosingApps are the lists of tokens that will be
420 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700421 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700422 String mNextAppTransitionPackage;
423 int mNextAppTransitionEnter;
424 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700426 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 boolean mAppTransitionTimeout = false;
428 boolean mStartingIconInTransition = false;
429 boolean mSkipAppTransitionAnimation = false;
430 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
431 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700432 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
433 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 H mH = new H();
438
439 WindowState mCurrentFocus = null;
440 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 // This just indicates the window the input method is on top of, not
443 // necessarily the window its input is going to.
444 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 boolean mInputMethodTargetWaitingAnim;
446 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 WindowState mInputMethodWindow = null;
449 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
450
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700451 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800452
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700453 // If non-null, this is the currently visible window that is associated
454 // with the wallpaper.
455 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700456 // If non-null, we are in the middle of animating from one wallpaper target
457 // to another, and this is the lower one in Z-order.
458 WindowState mLowerWallpaperTarget = null;
459 // If non-null, we are in the middle of animating from one wallpaper target
460 // to another, and this is the higher one in Z-order.
461 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800462 // Window currently running an animation that has requested it be detached
463 // from the wallpaper. This means we need to ensure the wallpaper is
464 // visible behind it in case it animates in a way that would allow it to be
465 // seen.
466 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700467 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700468 float mLastWallpaperX = -1;
469 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800470 float mLastWallpaperXStep = -1;
471 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700472 // This is set when we are waiting for a wallpaper to tell us it is done
473 // changing its scroll position.
474 WindowState mWaitingOnWallpaper;
475 // The last time we had a timeout when waiting for a wallpaper.
476 long mLastWallpaperTimeoutTime;
477 // We give a wallpaper up to 150ms to finish scrolling.
478 static final long WALLPAPER_TIMEOUT = 150;
479 // Time we wait after a timeout before trying to wait again.
480 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 AppWindowToken mFocusedApp = null;
483
484 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 float mWindowAnimationScale = 1.0f;
487 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700488
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700489 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490
491 // Who is holding the screen on.
492 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700493 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700494
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700495 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700498 * Drag/drop state
499 */
500 class DragState {
501 IBinder mToken;
502 Surface mSurface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800503 int mFlags;
Chris Tate7b362e42010-11-04 16:02:52 -0700504 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700505 ClipData mData;
506 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700507 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700508 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700509 float mThumbOffsetX, mThumbOffsetY;
510 InputChannel mServerChannel, mClientChannel;
511 WindowState mTargetWindow;
512 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700513 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700514
Christopher Tateccd24de2011-01-12 15:02:55 -0800515 boolean mPerformDeferredRotation;
516 int mRotation;
517 int mAnimFlags;
518
Christopher Tatea53146c2010-09-07 11:57:52 -0700519 private final Rect tmpRect = new Rect();
520
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800521 DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700522 mToken = token;
523 mSurface = surface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800524 mFlags = flags;
Chris Tate7b362e42010-11-04 16:02:52 -0700525 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700526 mNotifiedWindows = new ArrayList<WindowState>();
527 }
528
529 void reset() {
530 if (mSurface != null) {
531 mSurface.destroy();
532 }
533 mSurface = null;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800534 mFlags = 0;
Chris Tate7b362e42010-11-04 16:02:52 -0700535 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700536 mToken = null;
537 mData = null;
538 mThumbOffsetX = mThumbOffsetY = 0;
539 mNotifiedWindows = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800540 mPerformDeferredRotation = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700541 }
542
543 void register() {
544 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
545 if (mClientChannel != null) {
546 Slog.e(TAG, "Duplicate register of drag input channel");
547 } else {
548 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
549 mServerChannel = channels[0];
550 mClientChannel = channels[1];
Jeff Brown928e0542011-01-10 11:17:36 -0800551 mInputManager.registerInputChannel(mServerChannel, null);
Christopher Tatea53146c2010-09-07 11:57:52 -0700552 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
553 mH.getLooper().getQueue());
554 }
555 }
556
557 void unregister() {
558 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
559 if (mClientChannel == null) {
560 Slog.e(TAG, "Unregister of nonexistent drag input channel");
561 } else {
562 mInputManager.unregisterInputChannel(mServerChannel);
563 InputQueue.unregisterInputChannel(mClientChannel);
564 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700565 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700566 mClientChannel = null;
567 mServerChannel = null;
568 }
569 }
570
Chris Tatea32dcf72010-10-14 12:13:50 -0700571 int getDragLayerLw() {
572 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
573 * TYPE_LAYER_MULTIPLIER
574 + TYPE_LAYER_OFFSET;
575 }
576
Christopher Tatea53146c2010-09-07 11:57:52 -0700577 /* call out to each visible window/session informing it about the drag
578 */
Chris Tateb8203e92010-10-12 14:23:21 -0700579 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700580 // Cache a base-class instance of the clip metadata so that parceling
581 // works correctly in calling out to the apps.
Dianne Hackbornf834dfa2010-10-26 12:43:57 -0700582 mDataDescription = mData.getDescription();
Christopher Tatea53146c2010-09-07 11:57:52 -0700583 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700584 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700585
586 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700587 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700588 }
589
Christopher Tate2c095f32010-10-04 14:13:40 -0700590 final int N = mWindows.size();
591 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700592 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700593 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700594 }
595
596 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
597 * designated window is potentially a drop recipient. There are race situations
598 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
599 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700600 *
601 * This method clones the 'event' parameter if it's being delivered to the same
602 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700603 */
Chris Tateb478f462010-10-15 16:02:26 -0700604 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
605 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700606 // Don't actually send the event if the drag is supposed to be pinned
607 // to the originating window but 'newWin' is not that window.
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800608 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700609 final IBinder winBinder = newWin.mClient.asBinder();
610 if (winBinder != mLocalWin) {
611 if (DEBUG_DRAG) {
612 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
613 }
614 return;
615 }
616 }
617
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700618 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700619 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
620 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800621 null, desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700622 try {
623 newWin.mClient.dispatchDragEvent(event);
624 // track each window that we've notified that the drag is starting
625 mNotifiedWindows.add(newWin);
626 } catch (RemoteException e) {
627 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700628 } finally {
629 // if the callee was local, the dispatch has already recycled the event
630 if (Process.myPid() != newWin.mSession.mPid) {
631 event.recycle();
632 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700633 }
634 }
635 }
636
637 /* helper - construct and send a DRAG_STARTED event only if the window has not
638 * previously been notified, i.e. it became visible after the drag operation
639 * was begun. This is a rare case.
640 */
641 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700642 if (mDragInProgress) {
643 // If we have sent the drag-started, we needn't do so again
644 for (WindowState ws : mNotifiedWindows) {
645 if (ws == newWin) {
646 return;
647 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700648 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700649 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700650 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700651 }
Chris Tateb478f462010-10-15 16:02:26 -0700652 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700653 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700654 }
655
Chris Tated4533f142010-10-19 15:15:08 -0700656 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700657 if (DEBUG_DRAG) {
658 Slog.d(TAG, "broadcasting DRAG_ENDED");
659 }
Chris Tated4533f142010-10-19 15:15:08 -0700660 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
Christopher Tate407b4e92010-11-30 17:14:08 -0800661 0, 0, null, null, null, mDragResult);
Chris Tated4533f142010-10-19 15:15:08 -0700662 for (WindowState ws: mNotifiedWindows) {
663 try {
664 ws.mClient.dispatchDragEvent(evt);
665 } catch (RemoteException e) {
666 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700667 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700668 }
Chris Tated4533f142010-10-19 15:15:08 -0700669 mNotifiedWindows.clear();
670 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700671 evt.recycle();
672 }
673
Chris Tated4533f142010-10-19 15:15:08 -0700674 void endDragLw() {
675 mDragState.broadcastDragEndedLw();
676
677 // stop intercepting input
678 mDragState.unregister();
679 mInputMonitor.updateInputWindowsLw();
680
Christopher Tateccd24de2011-01-12 15:02:55 -0800681 // Retain the parameters of any deferred rotation operation so
682 // that we can perform it after the reset / unref of the drag state
683 final boolean performRotation = mPerformDeferredRotation;
684 final int rotation = mRotation;
685 final int animFlags = mAnimFlags;
686
Chris Tated4533f142010-10-19 15:15:08 -0700687 // free our resources and drop all the object references
688 mDragState.reset();
689 mDragState = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800690
691 // Now that we've officially ended the drag, execute any
692 // deferred rotation
693 if (performRotation) {
694 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
695 boolean changed = setRotationUncheckedLocked(rotation, animFlags);
696 if (changed) {
697 sendNewConfiguration();
698 }
699 }
Chris Tated4533f142010-10-19 15:15:08 -0700700 }
701
Christopher Tatea53146c2010-09-07 11:57:52 -0700702 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700703 final int myPid = Process.myPid();
704
705 // Move the surface to the given touch
706 mSurface.openTransaction();
707 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
708 mSurface.closeTransaction();
709
710 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700711 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800712 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700713 final IBinder touchedBinder = touchedWin.mClient.asBinder();
714 if (touchedBinder != mLocalWin) {
715 // This drag is pinned only to the originating window, but the drag
716 // point is outside that window. Pretend it's over empty space.
717 touchedWin = null;
718 }
719 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700720 try {
721 // have we dragged over a new window?
722 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
723 if (DEBUG_DRAG) {
724 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
725 }
726 // force DRAG_EXITED_EVENT if appropriate
727 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700728 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800729 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700730 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700731 if (myPid != mTargetWindow.mSession.mPid) {
732 evt.recycle();
733 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700734 }
735 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700736 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700737 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
738 }
739 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700740 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800741 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700742 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700743 if (myPid != touchedWin.mSession.mPid) {
744 evt.recycle();
745 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700746 }
747 } catch (RemoteException e) {
748 Slog.w(TAG, "can't send drag notification to windows");
749 }
750 mTargetWindow = touchedWin;
751 }
752
Chris Tated4533f142010-10-19 15:15:08 -0700753 // Tell the drop target about the data. Returns 'true' if we can immediately
754 // dispatch the global drag-ended message, 'false' if we need to wait for a
755 // result from the recipient.
756 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700757 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700758 if (touchedWin == null) {
759 // "drop" outside a valid window -- no recipient to apply a
760 // timeout to, and we can send the drag-ended message immediately.
761 mDragResult = false;
762 return true;
763 }
764
765 if (DEBUG_DRAG) {
766 Slog.d(TAG, "sending DROP to " + touchedWin);
767 }
768 final int myPid = Process.myPid();
769 final IBinder token = touchedWin.mClient.asBinder();
770 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
771 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800772 null, null, mData, false);
Chris Tated4533f142010-10-19 15:15:08 -0700773 try {
774 touchedWin.mClient.dispatchDragEvent(evt);
775
776 // 5 second timeout for this window to respond to the drop
777 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
778 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
779 mH.sendMessageDelayed(msg, 5000);
780 } catch (RemoteException e) {
781 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
782 return true;
783 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700784 if (myPid != touchedWin.mSession.mPid) {
785 evt.recycle();
786 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700787 }
Chris Tated4533f142010-10-19 15:15:08 -0700788 mToken = token;
789 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700790 }
791
792 // Find the visible, touch-deliverable window under the given point
793 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
794 WindowState touchedWin = null;
795 final int x = (int) xf;
796 final int y = (int) yf;
797 final ArrayList<WindowState> windows = mWindows;
798 final int N = windows.size();
799 for (int i = N - 1; i >= 0; i--) {
800 WindowState child = windows.get(i);
801 final int flags = child.mAttrs.flags;
802 if (!child.isVisibleLw()) {
803 // not visible == don't tell about drags
804 continue;
805 }
806 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
807 // not touchable == don't tell about drags
808 continue;
809 }
810 // account for the window's decor etc
811 tmpRect.set(child.mFrame);
812 if (child.mTouchableInsets == ViewTreeObserver
813 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
814 // The point is inside of the window if it is
815 // inside the frame, AND the content part of that
816 // frame that was given by the application.
817 tmpRect.left += child.mGivenContentInsets.left;
818 tmpRect.top += child.mGivenContentInsets.top;
819 tmpRect.right -= child.mGivenContentInsets.right;
820 tmpRect.bottom -= child.mGivenContentInsets.bottom;
821 } else if (child.mTouchableInsets == ViewTreeObserver
822 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
823 // The point is inside of the window if it is
824 // inside the frame, AND the visible part of that
825 // frame that was given by the application.
826 tmpRect.left += child.mGivenVisibleInsets.left;
827 tmpRect.top += child.mGivenVisibleInsets.top;
828 tmpRect.right -= child.mGivenVisibleInsets.right;
829 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
830 }
831 final int touchFlags = flags &
832 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
833 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
834 if (tmpRect.contains(x, y) || touchFlags == 0) {
835 // Found it
836 touchedWin = child;
837 break;
838 }
839 }
840
841 return touchedWin;
842 }
Christopher Tateccd24de2011-01-12 15:02:55 -0800843
844 void setDeferredRotation(int rotation, int animFlags) {
845 mRotation = rotation;
846 mAnimFlags = animFlags;
847 mPerformDeferredRotation = true;
848 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700849 }
850
851 DragState mDragState = null;
852 private final InputHandler mDragInputHandler = new BaseInputHandler() {
853 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700854 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
855 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700856 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700857 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
858 && mDragState != null) {
859 boolean endDrag = false;
860 final float newX = event.getRawX();
861 final float newY = event.getRawY();
862
Christopher Tatea53146c2010-09-07 11:57:52 -0700863 switch (event.getAction()) {
864 case MotionEvent.ACTION_DOWN: {
865 if (DEBUG_DRAG) {
866 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
867 }
868 } break;
869
870 case MotionEvent.ACTION_MOVE: {
871 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700872 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700873 mDragState.notifyMoveLw(newX, newY);
874 }
875 } break;
876
877 case MotionEvent.ACTION_UP: {
878 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
879 + newX + "," + newY);
880 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700881 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700882 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700883 } break;
884
885 case MotionEvent.ACTION_CANCEL: {
886 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
887 endDrag = true;
888 } break;
889 }
890
891 if (endDrag) {
892 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
893 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700894 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700895 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700896 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700897 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700898
899 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700900 }
901 } catch (Exception e) {
902 Slog.e(TAG, "Exception caught by drag handleMotion", e);
903 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700904 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700905 }
906 }
907 };
908
909 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 * Whether the UI is currently running in touch mode (not showing
911 * navigational focus because the user is directly pressing the screen).
912 */
913 boolean mInTouchMode = false;
914
915 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700916 private ArrayList<WindowChangeListener> mWindowChangeListeners =
917 new ArrayList<WindowChangeListener>();
918 private boolean mWindowsChanged = false;
919
920 public interface WindowChangeListener {
921 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700922 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924
Dianne Hackbornc485a602009-03-24 22:39:49 -0700925 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700926 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700927
928 // The frame use to limit the size of the app running in compatibility mode.
929 Rect mCompatibleScreenFrame = new Rect();
930 // The surface used to fill the outer rim of the app running in compatibility mode.
931 Surface mBackgroundFillerSurface = null;
932 boolean mBackgroundFillerShown = false;
933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 public static WindowManagerService main(Context context,
935 PowerManagerService pm, boolean haveInputMethods) {
936 WMThread thr = new WMThread(context, pm, haveInputMethods);
937 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 synchronized (thr) {
940 while (thr.mService == null) {
941 try {
942 thr.wait();
943 } catch (InterruptedException e) {
944 }
945 }
946 }
Romain Guy06882f82009-06-10 13:36:04 -0700947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 return thr.mService;
949 }
Romain Guy06882f82009-06-10 13:36:04 -0700950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 static class WMThread extends Thread {
952 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 private final Context mContext;
955 private final PowerManagerService mPM;
956 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 public WMThread(Context context, PowerManagerService pm,
959 boolean haveInputMethods) {
960 super("WindowManager");
961 mContext = context;
962 mPM = pm;
963 mHaveInputMethods = haveInputMethods;
964 }
Romain Guy06882f82009-06-10 13:36:04 -0700965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 public void run() {
967 Looper.prepare();
968 WindowManagerService s = new WindowManagerService(mContext, mPM,
969 mHaveInputMethods);
970 android.os.Process.setThreadPriority(
971 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700972 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 synchronized (this) {
975 mService = s;
976 notifyAll();
977 }
Romain Guy06882f82009-06-10 13:36:04 -0700978
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700979 // For debug builds, log event loop stalls to dropbox for analysis.
980 if (StrictMode.conditionallyEnableDebugLogging()) {
981 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
982 }
983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 Looper.loop();
985 }
986 }
987
988 static class PolicyThread extends Thread {
989 private final WindowManagerPolicy mPolicy;
990 private final WindowManagerService mService;
991 private final Context mContext;
992 private final PowerManagerService mPM;
993 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 public PolicyThread(WindowManagerPolicy policy,
996 WindowManagerService service, Context context,
997 PowerManagerService pm) {
998 super("WindowManagerPolicy");
999 mPolicy = policy;
1000 mService = service;
1001 mContext = context;
1002 mPM = pm;
1003 }
Romain Guy06882f82009-06-10 13:36:04 -07001004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 public void run() {
1006 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -08001007 WindowManagerPolicyThread.set(this, Looper.myLooper());
1008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -08001010 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 android.os.Process.setThreadPriority(
1012 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001013 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -07001015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 synchronized (this) {
1017 mRunning = true;
1018 notifyAll();
1019 }
Romain Guy06882f82009-06-10 13:36:04 -07001020
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001021 // For debug builds, log event loop stalls to dropbox for analysis.
1022 if (StrictMode.conditionallyEnableDebugLogging()) {
1023 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
1024 }
1025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026 Looper.loop();
1027 }
1028 }
1029
1030 private WindowManagerService(Context context, PowerManagerService pm,
1031 boolean haveInputMethods) {
1032 mContext = context;
1033 mHaveInputMethods = haveInputMethods;
1034 mLimitedAlphaCompositing = context.getResources().getBoolean(
1035 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -07001036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 mPowerManager = pm;
1038 mPowerManager.setPolicy(mPolicy);
1039 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1040 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1041 "SCREEN_FROZEN");
1042 mScreenFrozenLock.setReferenceCounted(false);
1043
1044 mActivityManager = ActivityManagerNative.getDefault();
1045 mBatteryStats = BatteryStatsService.getService();
1046
1047 // Get persisted window scale setting
1048 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1049 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1050 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1051 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001052
Jim Miller284b62e2010-06-08 14:27:42 -07001053 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1054 IntentFilter filter = new IntentFilter();
1055 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1056 mContext.registerReceiver(mBroadcastReceiver, filter);
1057
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001058 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1059 "KEEP_SCREEN_ON_FLAG");
1060 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061
Jeff Browne33348b2010-07-15 23:54:05 -07001062 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1065 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 synchronized (thr) {
1068 while (!thr.mRunning) {
1069 try {
1070 thr.wait();
1071 } catch (InterruptedException e) {
1072 }
1073 }
1074 }
Romain Guy06882f82009-06-10 13:36:04 -07001075
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001076 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 // Add ourself to the Watchdog monitors.
1079 Watchdog.getInstance().addMonitor(this);
1080 }
1081
1082 @Override
1083 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1084 throws RemoteException {
1085 try {
1086 return super.onTransact(code, data, reply, flags);
1087 } catch (RuntimeException e) {
1088 // The window manager only throws security exceptions, so let's
1089 // log all others.
1090 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001091 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 }
1093 throw e;
1094 }
1095 }
1096
Jeff Browne33348b2010-07-15 23:54:05 -07001097 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001099 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 TAG, "Adding window " + window + " at "
1101 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1102 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001103 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 }
1105
Jeff Browne33348b2010-07-15 23:54:05 -07001106 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001108 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 TAG, "Adding window " + window + " at "
1110 + i + " of " + mWindows.size() + " (before " + pos + ")");
1111 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001112 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 }
1114
1115 //This method finds out the index of a window that has the same app token as
1116 //win. used for z ordering the windows in mWindows
1117 private int findIdxBasedOnAppTokens(WindowState win) {
1118 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001119 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 int jmax = localmWindows.size();
1121 if(jmax == 0) {
1122 return -1;
1123 }
1124 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001125 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 if(wentry.mAppToken == win.mAppToken) {
1127 return j;
1128 }
1129 }
1130 return -1;
1131 }
Romain Guy06882f82009-06-10 13:36:04 -07001132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1134 final IWindow client = win.mClient;
1135 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001136 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 final int N = localmWindows.size();
1139 final WindowState attached = win.mAttachedWindow;
1140 int i;
1141 if (attached == null) {
1142 int tokenWindowsPos = token.windows.size();
1143 if (token.appWindowToken != null) {
1144 int index = tokenWindowsPos-1;
1145 if (index >= 0) {
1146 // If this application has existing windows, we
1147 // simply place the new window on top of them... but
1148 // keep the starting window on top.
1149 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1150 // Base windows go behind everything else.
1151 placeWindowBefore(token.windows.get(0), win);
1152 tokenWindowsPos = 0;
1153 } else {
1154 AppWindowToken atoken = win.mAppToken;
1155 if (atoken != null &&
1156 token.windows.get(index) == atoken.startingWindow) {
1157 placeWindowBefore(token.windows.get(index), win);
1158 tokenWindowsPos--;
1159 } else {
1160 int newIdx = findIdxBasedOnAppTokens(win);
1161 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001162 //there is a window above this one associated with the same
1163 //apptoken note that the window could be a floating window
1164 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001166 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1167 Slog.v(TAG, "Adding window " + win + " at "
1168 + (newIdx+1) + " of " + N);
1169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001171 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 }
1174 }
1175 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001176 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 TAG, "Figuring out where to add app window "
1178 + client.asBinder() + " (token=" + token + ")");
1179 // Figure out where the window should go, based on the
1180 // order of applications.
1181 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001182 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 for (i=NA-1; i>=0; i--) {
1184 AppWindowToken t = mAppTokens.get(i);
1185 if (t == token) {
1186 i--;
1187 break;
1188 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001189
Dianne Hackborna8f60182009-09-01 19:01:50 -07001190 // We haven't reached the token yet; if this token
1191 // is not going to the bottom and has windows, we can
1192 // use it as an anchor for when we do reach the token.
1193 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 pos = t.windows.get(0);
1195 }
1196 }
1197 // We now know the index into the apps. If we found
1198 // an app window above, that gives us the position; else
1199 // we need to look some more.
1200 if (pos != null) {
1201 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001202 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 if (atoken != null) {
1204 final int NC = atoken.windows.size();
1205 if (NC > 0) {
1206 WindowState bottom = atoken.windows.get(0);
1207 if (bottom.mSubLayer < 0) {
1208 pos = bottom;
1209 }
1210 }
1211 }
1212 placeWindowBefore(pos, win);
1213 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001214 // Continue looking down until we find the first
1215 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 while (i >= 0) {
1217 AppWindowToken t = mAppTokens.get(i);
1218 final int NW = t.windows.size();
1219 if (NW > 0) {
1220 pos = t.windows.get(NW-1);
1221 break;
1222 }
1223 i--;
1224 }
1225 if (pos != null) {
1226 // Move in front of any windows attached to this
1227 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001228 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 if (atoken != null) {
1230 final int NC = atoken.windows.size();
1231 if (NC > 0) {
1232 WindowState top = atoken.windows.get(NC-1);
1233 if (top.mSubLayer >= 0) {
1234 pos = top;
1235 }
1236 }
1237 }
1238 placeWindowAfter(pos, win);
1239 } else {
1240 // Just search for the start of this layer.
1241 final int myLayer = win.mBaseLayer;
1242 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001243 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001244 if (w.mBaseLayer > myLayer) {
1245 break;
1246 }
1247 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001248 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1249 Slog.v(TAG, "Adding window " + win + " at "
1250 + i + " of " + N);
1251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001253 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 }
1255 }
1256 }
1257 } else {
1258 // Figure out where window should go, based on layer.
1259 final int myLayer = win.mBaseLayer;
1260 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001261 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 i++;
1263 break;
1264 }
1265 }
1266 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001267 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001268 TAG, "Adding window " + win + " at "
1269 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001271 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 }
1273 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001274 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 token.windows.add(tokenWindowsPos, win);
1276 }
1277
1278 } else {
1279 // Figure out this window's ordering relative to the window
1280 // it is attached to.
1281 final int NA = token.windows.size();
1282 final int sublayer = win.mSubLayer;
1283 int largestSublayer = Integer.MIN_VALUE;
1284 WindowState windowWithLargestSublayer = null;
1285 for (i=0; i<NA; i++) {
1286 WindowState w = token.windows.get(i);
1287 final int wSublayer = w.mSubLayer;
1288 if (wSublayer >= largestSublayer) {
1289 largestSublayer = wSublayer;
1290 windowWithLargestSublayer = w;
1291 }
1292 if (sublayer < 0) {
1293 // For negative sublayers, we go below all windows
1294 // in the same sublayer.
1295 if (wSublayer >= sublayer) {
1296 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001297 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 token.windows.add(i, win);
1299 }
1300 placeWindowBefore(
1301 wSublayer >= 0 ? attached : w, win);
1302 break;
1303 }
1304 } else {
1305 // For positive sublayers, we go above all windows
1306 // in the same sublayer.
1307 if (wSublayer > sublayer) {
1308 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001309 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 token.windows.add(i, win);
1311 }
1312 placeWindowBefore(w, win);
1313 break;
1314 }
1315 }
1316 }
1317 if (i >= NA) {
1318 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001319 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 token.windows.add(win);
1321 }
1322 if (sublayer < 0) {
1323 placeWindowBefore(attached, win);
1324 } else {
1325 placeWindowAfter(largestSublayer >= 0
1326 ? windowWithLargestSublayer
1327 : attached,
1328 win);
1329 }
1330 }
1331 }
Romain Guy06882f82009-06-10 13:36:04 -07001332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 if (win.mAppToken != null && addToToken) {
1334 win.mAppToken.allAppWindows.add(win);
1335 }
1336 }
Romain Guy06882f82009-06-10 13:36:04 -07001337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 static boolean canBeImeTarget(WindowState w) {
1339 final int fl = w.mAttrs.flags
1340 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1341 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1342 return w.isVisibleOrAdding();
1343 }
1344 return false;
1345 }
Romain Guy06882f82009-06-10 13:36:04 -07001346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001348 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 final int N = localmWindows.size();
1350 WindowState w = null;
1351 int i = N;
1352 while (i > 0) {
1353 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001354 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001355
Joe Onorato8a9b2202010-02-26 18:56:32 -08001356 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 // + Integer.toHexString(w.mAttrs.flags));
1358 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001359 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 // Yet more tricksyness! If this window is a "starting"
1362 // window, we do actually want to be on top of it, but
1363 // it is not -really- where input will go. So if the caller
1364 // is not actually looking to move the IME, look down below
1365 // for a real window to target...
1366 if (!willMove
1367 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1368 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001369 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1371 i--;
1372 w = wb;
1373 }
1374 }
1375 break;
1376 }
1377 }
Romain Guy06882f82009-06-10 13:36:04 -07001378
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001379 // Now, a special case -- if the last target's window is in the
1380 // process of exiting, and is above the new target, keep on the
1381 // last target to avoid flicker. Consider for example a Dialog with
1382 // the IME shown: when the Dialog is dismissed, we want to keep
1383 // the IME above it until it is completely gone so it doesn't drop
1384 // behind the dialog or its full-screen scrim.
1385 if (mInputMethodTarget != null && w != null
1386 && mInputMethodTarget.isDisplayedLw()
1387 && mInputMethodTarget.mExiting) {
1388 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1389 w = mInputMethodTarget;
1390 i = localmWindows.indexOf(w);
1391 }
1392 }
Romain Guy06882f82009-06-10 13:36:04 -07001393
Joe Onorato8a9b2202010-02-26 18:56:32 -08001394 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 if (willMove && w != null) {
1398 final WindowState curTarget = mInputMethodTarget;
1399 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 // Now some fun for dealing with window animations that
1402 // modify the Z order. We need to look at all windows below
1403 // the current target that are in this app, finding the highest
1404 // visible one in layering.
1405 AppWindowToken token = curTarget.mAppToken;
1406 WindowState highestTarget = null;
1407 int highestPos = 0;
1408 if (token.animating || token.animation != null) {
1409 int pos = 0;
1410 pos = localmWindows.indexOf(curTarget);
1411 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001412 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 if (win.mAppToken != token) {
1414 break;
1415 }
1416 if (!win.mRemoved) {
1417 if (highestTarget == null || win.mAnimLayer >
1418 highestTarget.mAnimLayer) {
1419 highestTarget = win;
1420 highestPos = pos;
1421 }
1422 }
1423 pos--;
1424 }
1425 }
Romain Guy06882f82009-06-10 13:36:04 -07001426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001428 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 + mNextAppTransition + " " + highestTarget
1430 + " animating=" + highestTarget.isAnimating()
1431 + " layer=" + highestTarget.mAnimLayer
1432 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001433
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001434 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 // If we are currently setting up for an animation,
1436 // hold everything until we can find out what will happen.
1437 mInputMethodTargetWaitingAnim = true;
1438 mInputMethodTarget = highestTarget;
1439 return highestPos + 1;
1440 } else if (highestTarget.isAnimating() &&
1441 highestTarget.mAnimLayer > w.mAnimLayer) {
1442 // If the window we are currently targeting is involved
1443 // with an animation, and it is on top of the next target
1444 // we will be over, then hold off on moving until
1445 // that is done.
1446 mInputMethodTarget = highestTarget;
1447 return highestPos + 1;
1448 }
1449 }
1450 }
1451 }
Romain Guy06882f82009-06-10 13:36:04 -07001452
Joe Onorato8a9b2202010-02-26 18:56:32 -08001453 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 if (w != null) {
1455 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001456 if (DEBUG_INPUT_METHOD) {
1457 RuntimeException e = null;
1458 if (!HIDE_STACK_CRAWLS) {
1459 e = new RuntimeException();
1460 e.fillInStackTrace();
1461 }
1462 Slog.w(TAG, "Moving IM target from "
1463 + mInputMethodTarget + " to " + w, e);
1464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 mInputMethodTarget = w;
1466 if (w.mAppToken != null) {
1467 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1468 } else {
1469 setInputMethodAnimLayerAdjustment(0);
1470 }
1471 }
1472 return i+1;
1473 }
1474 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001475 if (DEBUG_INPUT_METHOD) {
1476 RuntimeException e = null;
1477 if (!HIDE_STACK_CRAWLS) {
1478 e = new RuntimeException();
1479 e.fillInStackTrace();
1480 }
1481 Slog.w(TAG, "Moving IM target from "
1482 + mInputMethodTarget + " to null", e);
1483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 mInputMethodTarget = null;
1485 setInputMethodAnimLayerAdjustment(0);
1486 }
1487 return -1;
1488 }
Romain Guy06882f82009-06-10 13:36:04 -07001489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 void addInputMethodWindowToListLocked(WindowState win) {
1491 int pos = findDesiredInputMethodWindowIndexLocked(true);
1492 if (pos >= 0) {
1493 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001494 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001495 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001497 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 moveInputMethodDialogsLocked(pos+1);
1499 return;
1500 }
1501 win.mTargetAppToken = null;
1502 addWindowToListInOrderLocked(win, true);
1503 moveInputMethodDialogsLocked(pos);
1504 }
Romain Guy06882f82009-06-10 13:36:04 -07001505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001507 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 mInputMethodAnimLayerAdjustment = adj;
1509 WindowState imw = mInputMethodWindow;
1510 if (imw != null) {
1511 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001512 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 + " anim layer: " + imw.mAnimLayer);
1514 int wi = imw.mChildWindows.size();
1515 while (wi > 0) {
1516 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001517 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001519 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 + " anim layer: " + cw.mAnimLayer);
1521 }
1522 }
1523 int di = mInputMethodDialogs.size();
1524 while (di > 0) {
1525 di --;
1526 imw = mInputMethodDialogs.get(di);
1527 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001528 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 + " anim layer: " + imw.mAnimLayer);
1530 }
1531 }
Romain Guy06882f82009-06-10 13:36:04 -07001532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1534 int wpos = mWindows.indexOf(win);
1535 if (wpos >= 0) {
1536 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001537 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001539 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 int NC = win.mChildWindows.size();
1541 while (NC > 0) {
1542 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001543 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 int cpos = mWindows.indexOf(cw);
1545 if (cpos >= 0) {
1546 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001547 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001548 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 mWindows.remove(cpos);
1550 }
1551 }
1552 }
1553 return interestingPos;
1554 }
Romain Guy06882f82009-06-10 13:36:04 -07001555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 private void reAddWindowToListInOrderLocked(WindowState win) {
1557 addWindowToListInOrderLocked(win, false);
1558 // This is a hack to get all of the child windows added as well
1559 // at the right position. Child windows should be rare and
1560 // this case should be rare, so it shouldn't be that big a deal.
1561 int wpos = mWindows.indexOf(win);
1562 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001563 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001564 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001566 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 reAddWindowLocked(wpos, win);
1568 }
1569 }
Romain Guy06882f82009-06-10 13:36:04 -07001570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 void logWindowList(String prefix) {
1572 int N = mWindows.size();
1573 while (N > 0) {
1574 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001575 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 }
1577 }
Romain Guy06882f82009-06-10 13:36:04 -07001578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 void moveInputMethodDialogsLocked(int pos) {
1580 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001583 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 for (int i=0; i<N; i++) {
1585 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1586 }
1587 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001588 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 logWindowList(" ");
1590 }
Romain Guy06882f82009-06-10 13:36:04 -07001591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 if (pos >= 0) {
1593 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1594 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001595 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 if (wp == mInputMethodWindow) {
1597 pos++;
1598 }
1599 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001600 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001601 for (int i=0; i<N; i++) {
1602 WindowState win = dialogs.get(i);
1603 win.mTargetAppToken = targetAppToken;
1604 pos = reAddWindowLocked(pos, win);
1605 }
1606 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001607 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 logWindowList(" ");
1609 }
1610 return;
1611 }
1612 for (int i=0; i<N; i++) {
1613 WindowState win = dialogs.get(i);
1614 win.mTargetAppToken = null;
1615 reAddWindowToListInOrderLocked(win);
1616 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001617 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 logWindowList(" ");
1619 }
1620 }
1621 }
Romain Guy06882f82009-06-10 13:36:04 -07001622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1624 final WindowState imWin = mInputMethodWindow;
1625 final int DN = mInputMethodDialogs.size();
1626 if (imWin == null && DN == 0) {
1627 return false;
1628 }
Romain Guy06882f82009-06-10 13:36:04 -07001629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1631 if (imPos >= 0) {
1632 // In this case, the input method windows are to be placed
1633 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 // First check to see if the input method windows are already
1636 // located here, and contiguous.
1637 final int N = mWindows.size();
1638 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001639 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 // Figure out the actual input method window that should be
1642 // at the bottom of their stack.
1643 WindowState baseImWin = imWin != null
1644 ? imWin : mInputMethodDialogs.get(0);
1645 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001646 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647 if (cw.mSubLayer < 0) baseImWin = cw;
1648 }
Romain Guy06882f82009-06-10 13:36:04 -07001649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 if (firstImWin == baseImWin) {
1651 // The windows haven't moved... but are they still contiguous?
1652 // First find the top IM window.
1653 int pos = imPos+1;
1654 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001655 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 break;
1657 }
1658 pos++;
1659 }
1660 pos++;
1661 // Now there should be no more input method windows above.
1662 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001663 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 break;
1665 }
1666 pos++;
1667 }
1668 if (pos >= N) {
1669 // All is good!
1670 return false;
1671 }
1672 }
Romain Guy06882f82009-06-10 13:36:04 -07001673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001674 if (imWin != null) {
1675 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 logWindowList(" ");
1678 }
1679 imPos = tmpRemoveWindowLocked(imPos, imWin);
1680 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001681 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 logWindowList(" ");
1683 }
1684 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1685 reAddWindowLocked(imPos, imWin);
1686 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688 logWindowList(" ");
1689 }
1690 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1691 } else {
1692 moveInputMethodDialogsLocked(imPos);
1693 }
Romain Guy06882f82009-06-10 13:36:04 -07001694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 } else {
1696 // In this case, the input method windows go in a fixed layer,
1697 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001700 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 tmpRemoveWindowLocked(0, imWin);
1702 imWin.mTargetAppToken = null;
1703 reAddWindowToListInOrderLocked(imWin);
1704 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001705 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 logWindowList(" ");
1707 }
1708 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1709 } else {
1710 moveInputMethodDialogsLocked(-1);;
1711 }
Romain Guy06882f82009-06-10 13:36:04 -07001712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 }
Romain Guy06882f82009-06-10 13:36:04 -07001714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715 if (needAssignLayers) {
1716 assignLayersLocked();
1717 }
Romain Guy06882f82009-06-10 13:36:04 -07001718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 return true;
1720 }
Romain Guy06882f82009-06-10 13:36:04 -07001721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 void adjustInputMethodDialogsLocked() {
1723 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1724 }
Romain Guy06882f82009-06-10 13:36:04 -07001725
Dianne Hackborn25994b42009-09-04 14:21:19 -07001726 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001727 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001728 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1729 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1730 ? wallpaperTarget.mAppToken.animation : null)
1731 + " upper=" + mUpperWallpaperTarget
1732 + " lower=" + mLowerWallpaperTarget);
1733 return (wallpaperTarget != null
1734 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1735 && wallpaperTarget.mAppToken.animation != null)))
1736 || mUpperWallpaperTarget != null
1737 || mLowerWallpaperTarget != null;
1738 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001739
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001740 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1741 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001742
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001743 int adjustWallpaperWindowsLocked() {
1744 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001745
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001746 final int dw = mDisplay.getWidth();
1747 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001748
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001749 // First find top-most window that has asked to be on top of the
1750 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001751 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001752 int N = localmWindows.size();
1753 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001754 WindowState foundW = null;
1755 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001756 WindowState topCurW = null;
1757 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001758 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001759 int i = N;
1760 while (i > 0) {
1761 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001762 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001763 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1764 if (topCurW == null) {
1765 topCurW = w;
1766 topCurI = i;
1767 }
1768 continue;
1769 }
1770 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001771 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001772 // If this window's app token is hidden and not animating,
1773 // it is of no interest to us.
1774 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001775 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001776 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001777 continue;
1778 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001779 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001780 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001781 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1782 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001783 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001784 && (mWallpaperTarget == w
1785 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001786 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001787 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001788 foundW = w;
1789 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001790 if (w == mWallpaperTarget && ((w.mAppToken != null
1791 && w.mAppToken.animation != null)
1792 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001793 // The current wallpaper target is animating, so we'll
1794 // look behind it for another possible target and figure
1795 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001796 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001797 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001798 continue;
1799 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001800 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001801 } else if (w == mWindowDetachedWallpaper) {
1802 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001803 }
1804 }
1805
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001806 if (foundW == null && windowDetachedI >= 0) {
1807 if (DEBUG_WALLPAPER) Slog.v(TAG,
1808 "Found animating detached wallpaper activity: #" + i + "=" + w);
1809 foundW = w;
1810 foundI = windowDetachedI;
1811 }
1812
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001813 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001814 // If we are currently waiting for an app transition, and either
1815 // the current target or the next target are involved with it,
1816 // then hold off on doing anything with the wallpaper.
1817 // Note that we are checking here for just whether the target
1818 // is part of an app token... which is potentially overly aggressive
1819 // (the app token may not be involved in the transition), but good
1820 // enough (we'll just wait until whatever transition is pending
1821 // executes).
1822 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001823 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001824 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001825 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001826 }
1827 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001829 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001830 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001831 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001832 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001833
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001834 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001835 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001836 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001837 + " oldTarget: " + mWallpaperTarget);
1838 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001839
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001840 mLowerWallpaperTarget = null;
1841 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001842
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001843 WindowState oldW = mWallpaperTarget;
1844 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001845
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001846 // Now what is happening... if the current and new targets are
1847 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001848 if (foundW != null && oldW != null) {
1849 boolean oldAnim = oldW.mAnimation != null
1850 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1851 boolean foundAnim = foundW.mAnimation != null
1852 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001853 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001854 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001855 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001856 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001857 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001858 int oldI = localmWindows.indexOf(oldW);
1859 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001860 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001861 }
1862 if (oldI >= 0) {
1863 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001865 + "=" + oldW + "; new#" + foundI
1866 + "=" + foundW);
1867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001868
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001869 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001870 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001871 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001872 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001873 }
1874 mWallpaperTarget = oldW;
1875 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001876
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001877 // Now set the upper and lower wallpaper targets
1878 // correctly, and make sure that we are positioning
1879 // the wallpaper below the lower.
1880 if (foundI > oldI) {
1881 // The new target is on top of the old one.
1882 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001883 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001884 }
1885 mUpperWallpaperTarget = foundW;
1886 mLowerWallpaperTarget = oldW;
1887 foundW = oldW;
1888 foundI = oldI;
1889 } else {
1890 // The new target is below the old one.
1891 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001892 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001893 }
1894 mUpperWallpaperTarget = oldW;
1895 mLowerWallpaperTarget = foundW;
1896 }
1897 }
1898 }
1899 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001900
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001901 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001902 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001903 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1904 || (mLowerWallpaperTarget.mAppToken != null
1905 && mLowerWallpaperTarget.mAppToken.animation != null);
1906 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1907 || (mUpperWallpaperTarget.mAppToken != null
1908 && mUpperWallpaperTarget.mAppToken.animation != null);
1909 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001910 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001911 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001912 }
1913 mLowerWallpaperTarget = null;
1914 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001915 }
1916 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001917
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001918 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001919 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001920 // The window is visible to the compositor... but is it visible
1921 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001922 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001923 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001924
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001925 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001926 // its layer adjustment. Only do this if we are not transfering
1927 // between two wallpaper targets.
1928 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001929 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001930 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001931
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001932 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1933 * TYPE_LAYER_MULTIPLIER
1934 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001935
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001936 // Now w is the window we are supposed to be behind... but we
1937 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001938 // AND any starting window associated with it, AND below the
1939 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001940 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001941 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001942 if (wb.mBaseLayer < maxLayer &&
1943 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001944 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001945 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001946 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001947 // This window is not related to the previous one in any
1948 // interesting way, so stop here.
1949 break;
1950 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001951 foundW = wb;
1952 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001953 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001954 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001955 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001956 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001957
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001958 if (foundW == null && topCurW != null) {
1959 // There is no wallpaper target, so it goes at the bottom.
1960 // We will assume it is the same place as last time, if known.
1961 foundW = topCurW;
1962 foundI = topCurI+1;
1963 } else {
1964 // Okay i is the position immediately above the wallpaper. Look at
1965 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001966 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001967 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001968
Dianne Hackborn284ac932009-08-28 10:34:25 -07001969 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001970 if (mWallpaperTarget.mWallpaperX >= 0) {
1971 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001972 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001973 }
1974 if (mWallpaperTarget.mWallpaperY >= 0) {
1975 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001976 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001977 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001978 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001979
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001980 // Start stepping backwards from here, ensuring that our wallpaper windows
1981 // are correctly placed.
1982 int curTokenIndex = mWallpaperTokens.size();
1983 while (curTokenIndex > 0) {
1984 curTokenIndex--;
1985 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001986 if (token.hidden == visible) {
1987 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1988 token.hidden = !visible;
1989 // Need to do a layout to ensure the wallpaper now has the
1990 // correct size.
1991 mLayoutNeeded = true;
1992 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001993
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001994 int curWallpaperIndex = token.windows.size();
1995 while (curWallpaperIndex > 0) {
1996 curWallpaperIndex--;
1997 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001998
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001999 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002000 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002001 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002002
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002003 // First, make sure the client has the current visibility
2004 // state.
2005 if (wallpaper.mWallpaperVisible != visible) {
2006 wallpaper.mWallpaperVisible = visible;
2007 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002008 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002009 "Setting visibility of wallpaper " + wallpaper
2010 + ": " + visible);
2011 wallpaper.mClient.dispatchAppVisibility(visible);
2012 } catch (RemoteException e) {
2013 }
2014 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002015
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002016 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002017 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002018 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002019
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002020 // First, if this window is at the current index, then all
2021 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002022 if (wallpaper == foundW) {
2023 foundI--;
2024 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07002025 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002026 continue;
2027 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002028
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002029 // The window didn't match... the current wallpaper window,
2030 // wherever it is, is in the wrong place, so make sure it is
2031 // not in the list.
2032 int oldIndex = localmWindows.indexOf(wallpaper);
2033 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002035 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002036 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002037 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002038 if (oldIndex < foundI) {
2039 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002040 }
2041 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002042
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002043 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002044 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
2045 Slog.v(TAG, "Moving wallpaper " + wallpaper
2046 + " from " + oldIndex + " to " + foundI);
2047 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002048
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002049 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002050 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002051 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002052 }
2053 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002054
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002055 return changed;
2056 }
2057
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002058 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002059 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002060 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002061 mWallpaperAnimLayerAdjustment = adj;
2062 int curTokenIndex = mWallpaperTokens.size();
2063 while (curTokenIndex > 0) {
2064 curTokenIndex--;
2065 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2066 int curWallpaperIndex = token.windows.size();
2067 while (curWallpaperIndex > 0) {
2068 curWallpaperIndex--;
2069 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2070 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002071 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002072 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002073 }
2074 }
2075 }
2076
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002077 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2078 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002079 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002080 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002081 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002082 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002083 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2084 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2085 changed = wallpaperWin.mXOffset != offset;
2086 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002087 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002088 + wallpaperWin + " x: " + offset);
2089 wallpaperWin.mXOffset = offset;
2090 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002091 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002092 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002093 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002094 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002095 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002096
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002097 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002098 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002099 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2100 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2101 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002102 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002103 + wallpaperWin + " y: " + offset);
2104 changed = true;
2105 wallpaperWin.mYOffset = offset;
2106 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002107 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002108 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002109 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002110 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002111 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002112
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002113 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002114 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002115 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002116 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2117 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002118 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002119 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002120 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002121 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002122 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2123 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002124 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002125 if (mWaitingOnWallpaper != null) {
2126 long start = SystemClock.uptimeMillis();
2127 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2128 < start) {
2129 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002130 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002131 "Waiting for offset complete...");
2132 mWindowMap.wait(WALLPAPER_TIMEOUT);
2133 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002134 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002135 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002136 if ((start+WALLPAPER_TIMEOUT)
2137 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002138 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002139 + wallpaperWin);
2140 mLastWallpaperTimeoutTime = start;
2141 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002142 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002143 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002144 }
2145 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002146 } catch (RemoteException e) {
2147 }
2148 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002149
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002150 return changed;
2151 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002152
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002153 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002154 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002155 if (mWaitingOnWallpaper != null &&
2156 mWaitingOnWallpaper.mClient.asBinder() == window) {
2157 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002158 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002159 }
2160 }
2161 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002162
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002163 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002164 final int dw = mDisplay.getWidth();
2165 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002166
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002167 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002168
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002169 WindowState target = mWallpaperTarget;
2170 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002171 if (target.mWallpaperX >= 0) {
2172 mLastWallpaperX = target.mWallpaperX;
2173 } else if (changingTarget.mWallpaperX >= 0) {
2174 mLastWallpaperX = changingTarget.mWallpaperX;
2175 }
2176 if (target.mWallpaperY >= 0) {
2177 mLastWallpaperY = target.mWallpaperY;
2178 } else if (changingTarget.mWallpaperY >= 0) {
2179 mLastWallpaperY = changingTarget.mWallpaperY;
2180 }
2181 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002182
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002183 int curTokenIndex = mWallpaperTokens.size();
2184 while (curTokenIndex > 0) {
2185 curTokenIndex--;
2186 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2187 int curWallpaperIndex = token.windows.size();
2188 while (curWallpaperIndex > 0) {
2189 curWallpaperIndex--;
2190 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2191 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2192 wallpaper.computeShownFrameLocked();
2193 changed = true;
2194 // We only want to be synchronous with one wallpaper.
2195 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002196 }
2197 }
2198 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002199
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002200 return changed;
2201 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002202
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002203 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002204 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002205 final int dw = mDisplay.getWidth();
2206 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002207
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002208 int curTokenIndex = mWallpaperTokens.size();
2209 while (curTokenIndex > 0) {
2210 curTokenIndex--;
2211 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002212 if (token.hidden == visible) {
2213 token.hidden = !visible;
2214 // Need to do a layout to ensure the wallpaper now has the
2215 // correct size.
2216 mLayoutNeeded = true;
2217 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002218
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002219 int curWallpaperIndex = token.windows.size();
2220 while (curWallpaperIndex > 0) {
2221 curWallpaperIndex--;
2222 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2223 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002224 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002225 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002226
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002227 if (wallpaper.mWallpaperVisible != visible) {
2228 wallpaper.mWallpaperVisible = visible;
2229 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002230 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002231 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002232 + ": " + visible);
2233 wallpaper.mClient.dispatchAppVisibility(visible);
2234 } catch (RemoteException e) {
2235 }
2236 }
2237 }
2238 }
2239 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 public int addWindow(Session session, IWindow client,
2242 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002243 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 int res = mPolicy.checkAddPermission(attrs);
2245 if (res != WindowManagerImpl.ADD_OKAY) {
2246 return res;
2247 }
Romain Guy06882f82009-06-10 13:36:04 -07002248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 boolean reportNewConfig = false;
2250 WindowState attachedWindow = null;
2251 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002252 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002256 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 }
Romain Guy06882f82009-06-10 13:36:04 -07002258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002260 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2262 }
2263
2264 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002265 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002267 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 + attrs.token + ". Aborting.");
2269 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2270 }
2271 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2272 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002273 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 + attrs.token + ". Aborting.");
2275 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2276 }
2277 }
2278
2279 boolean addToken = false;
2280 WindowToken token = mTokenMap.get(attrs.token);
2281 if (token == null) {
2282 if (attrs.type >= FIRST_APPLICATION_WINDOW
2283 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002284 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 + attrs.token + ". Aborting.");
2286 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2287 }
2288 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002289 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 + attrs.token + ". Aborting.");
2291 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2292 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002293 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002294 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002295 + attrs.token + ". Aborting.");
2296 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 token = new WindowToken(attrs.token, -1, false);
2299 addToken = true;
2300 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2301 && attrs.type <= LAST_APPLICATION_WINDOW) {
2302 AppWindowToken atoken = token.appWindowToken;
2303 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002304 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 + token + ". Aborting.");
2306 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2307 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002308 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 + token + ". Aborting.");
2310 return WindowManagerImpl.ADD_APP_EXITING;
2311 }
2312 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2313 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002314 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2316 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2317 }
2318 } else if (attrs.type == TYPE_INPUT_METHOD) {
2319 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002320 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 + attrs.token + ". Aborting.");
2322 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2323 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002324 } else if (attrs.type == TYPE_WALLPAPER) {
2325 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002326 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002327 + attrs.token + ". Aborting.");
2328 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 }
2331
2332 win = new WindowState(session, client, token,
2333 attachedWindow, attrs, viewVisibility);
2334 if (win.mDeathRecipient == null) {
2335 // Client has apparently died, so there is no reason to
2336 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002337 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 + " that is dead, aborting.");
2339 return WindowManagerImpl.ADD_APP_EXITING;
2340 }
2341
2342 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 res = mPolicy.prepareAddWindowLw(win, attrs);
2345 if (res != WindowManagerImpl.ADD_OKAY) {
2346 return res;
2347 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002348
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002349 if (outInputChannel != null) {
2350 String name = win.makeInputChannelName();
2351 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2352 win.mInputChannel = inputChannels[0];
2353 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2354
Jeff Brown928e0542011-01-10 11:17:36 -08002355 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357
2358 // From now on, no exceptions or errors allowed!
2359
2360 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002361
Dianne Hackborn5132b372010-07-29 12:51:35 -07002362 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 if (addToken) {
2365 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 }
2367 win.attach();
2368 mWindowMap.put(client.asBinder(), win);
2369
2370 if (attrs.type == TYPE_APPLICATION_STARTING &&
2371 token.appWindowToken != null) {
2372 token.appWindowToken.startingWindow = win;
2373 }
2374
2375 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 if (attrs.type == TYPE_INPUT_METHOD) {
2378 mInputMethodWindow = win;
2379 addInputMethodWindowToListLocked(win);
2380 imMayMove = false;
2381 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2382 mInputMethodDialogs.add(win);
2383 addWindowToListInOrderLocked(win, true);
2384 adjustInputMethodDialogsLocked();
2385 imMayMove = false;
2386 } else {
2387 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002388 if (attrs.type == TYPE_WALLPAPER) {
2389 mLastWallpaperTimeoutTime = 0;
2390 adjustWallpaperWindowsLocked();
2391 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002392 adjustWallpaperWindowsLocked();
2393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002394 }
Romain Guy06882f82009-06-10 13:36:04 -07002395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 if (mInTouchMode) {
2401 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2402 }
2403 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2404 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2405 }
Romain Guy06882f82009-06-10 13:36:04 -07002406
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002407 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002409 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2410 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 imMayMove = false;
2412 }
2413 }
Romain Guy06882f82009-06-10 13:36:04 -07002414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002416 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 }
Romain Guy06882f82009-06-10 13:36:04 -07002418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 assignLayersLocked();
2420 // Don't do layout here, the window must call
2421 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 //dump();
2424
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002425 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002426 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002427 }
Jeff Brown349703e2010-06-22 01:27:15 -07002428
Joe Onorato8a9b2202010-02-26 18:56:32 -08002429 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 TAG, "New client " + client.asBinder()
2431 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002432
2433 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2434 reportNewConfig = true;
2435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 }
2437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 if (reportNewConfig) {
2439 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 return res;
2445 }
Romain Guy06882f82009-06-10 13:36:04 -07002446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 public void removeWindow(Session session, IWindow client) {
2448 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002449 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 if (win == null) {
2451 return;
2452 }
2453 removeWindowLocked(session, win);
2454 }
2455 }
Romain Guy06882f82009-06-10 13:36:04 -07002456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 public void removeWindowLocked(Session session, WindowState win) {
2458
Joe Onorato8a9b2202010-02-26 18:56:32 -08002459 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 TAG, "Remove " + win + " client="
2461 + Integer.toHexString(System.identityHashCode(
2462 win.mClient.asBinder()))
2463 + ", surface=" + win.mSurface);
2464
2465 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002466
2467 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002468
Joe Onorato8a9b2202010-02-26 18:56:32 -08002469 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2471 + " mExiting=" + win.mExiting
2472 + " isAnimating=" + win.isAnimating()
2473 + " app-animation="
2474 + (win.mAppToken != null ? win.mAppToken.animation : null)
2475 + " inPendingTransaction="
2476 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2477 + " mDisplayFrozen=" + mDisplayFrozen);
2478 // Visibility of the removed window. Will be used later to update orientation later on.
2479 boolean wasVisible = false;
2480 // First, see if we need to run an animation. If we do, we have
2481 // to hold off on removing the window until the animation is done.
2482 // If the display is frozen, just remove immediately, since the
2483 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002484 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 // If we are not currently running the exit animation, we
2486 // need to see about starting one.
2487 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2490 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2491 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2492 }
2493 // Try starting an animation.
2494 if (applyAnimationLocked(win, transit, false)) {
2495 win.mExiting = true;
2496 }
2497 }
2498 if (win.mExiting || win.isAnimating()) {
2499 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002500 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 win.mExiting = true;
2502 win.mRemoveOnExit = true;
2503 mLayoutNeeded = true;
2504 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2505 performLayoutAndPlaceSurfacesLocked();
2506 if (win.mAppToken != null) {
2507 win.mAppToken.updateReportedVisibilityLocked();
2508 }
2509 //dump();
2510 Binder.restoreCallingIdentity(origId);
2511 return;
2512 }
2513 }
2514
2515 removeWindowInnerLocked(session, win);
2516 // Removing a visible window will effect the computed orientation
2517 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002518 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002519 != mForcedAppOrientation
2520 && updateOrientationFromAppTokensLocked()) {
2521 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 }
2523 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2524 Binder.restoreCallingIdentity(origId);
2525 }
Romain Guy06882f82009-06-10 13:36:04 -07002526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002528 if (win.mRemoved) {
2529 // Nothing to do.
2530 return;
2531 }
2532
2533 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2534 WindowState cwin = win.mChildWindows.get(i);
2535 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2536 + win);
2537 removeWindowInnerLocked(cwin.mSession, cwin);
2538 }
2539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002540 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 if (mInputMethodTarget == win) {
2543 moveInputMethodWindowsIfNeededLocked(false);
2544 }
Romain Guy06882f82009-06-10 13:36:04 -07002545
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002546 if (false) {
2547 RuntimeException e = new RuntimeException("here");
2548 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002549 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002550 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 mPolicy.removeWindowLw(win);
2553 win.removeLocked();
2554
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002555 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 mWindowMap.remove(win.mClient.asBinder());
2557 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002558 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002559 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002560 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561
2562 if (mInputMethodWindow == win) {
2563 mInputMethodWindow = null;
2564 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2565 mInputMethodDialogs.remove(win);
2566 }
Romain Guy06882f82009-06-10 13:36:04 -07002567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 final WindowToken token = win.mToken;
2569 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002570 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571 token.windows.remove(win);
2572 if (atoken != null) {
2573 atoken.allAppWindows.remove(win);
2574 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002575 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 TAG, "**** Removing window " + win + ": count="
2577 + token.windows.size());
2578 if (token.windows.size() == 0) {
2579 if (!token.explicit) {
2580 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 } else if (atoken != null) {
2582 atoken.firstWindowDrawn = false;
2583 }
2584 }
2585
2586 if (atoken != null) {
2587 if (atoken.startingWindow == win) {
2588 atoken.startingWindow = null;
2589 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2590 // If this is the last window and we had requested a starting
2591 // transition window, well there is no point now.
2592 atoken.startingData = null;
2593 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2594 // If this is the last window except for a starting transition
2595 // window, we need to get rid of the starting transition.
2596 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002597 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 + ": no more real windows");
2599 }
2600 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2601 mH.sendMessage(m);
2602 }
2603 }
Romain Guy06882f82009-06-10 13:36:04 -07002604
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002605 if (win.mAttrs.type == TYPE_WALLPAPER) {
2606 mLastWallpaperTimeoutTime = 0;
2607 adjustWallpaperWindowsLocked();
2608 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002609 adjustWallpaperWindowsLocked();
2610 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 if (!mInLayout) {
2613 assignLayersLocked();
2614 mLayoutNeeded = true;
2615 performLayoutAndPlaceSurfacesLocked();
2616 if (win.mAppToken != null) {
2617 win.mAppToken.updateReportedVisibilityLocked();
2618 }
2619 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002620
2621 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 }
2623
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002624 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2625 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2626 + ": " + msg + " / " + w.mAttrs.getTitle();
2627 if (where != null) {
2628 Slog.i(TAG, str, where);
2629 } else {
2630 Slog.i(TAG, str);
2631 }
2632 }
2633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2635 long origId = Binder.clearCallingIdentity();
2636 try {
2637 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002638 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002640 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641 Surface.openTransaction();
2642 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002643 if (SHOW_TRANSACTIONS) logSurface(w,
2644 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 w.mSurface.setTransparentRegionHint(region);
2646 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002647 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 Surface.closeTransaction();
2649 }
2650 }
2651 }
2652 } finally {
2653 Binder.restoreCallingIdentity(origId);
2654 }
2655 }
2656
2657 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002658 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 Rect visibleInsets) {
2660 long origId = Binder.clearCallingIdentity();
2661 try {
2662 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002663 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 if (w != null) {
2665 w.mGivenInsetsPending = false;
2666 w.mGivenContentInsets.set(contentInsets);
2667 w.mGivenVisibleInsets.set(visibleInsets);
2668 w.mTouchableInsets = touchableInsets;
2669 mLayoutNeeded = true;
2670 performLayoutAndPlaceSurfacesLocked();
2671 }
2672 }
2673 } finally {
2674 Binder.restoreCallingIdentity(origId);
2675 }
2676 }
Romain Guy06882f82009-06-10 13:36:04 -07002677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 public void getWindowDisplayFrame(Session session, IWindow client,
2679 Rect outDisplayFrame) {
2680 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002681 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 if (win == null) {
2683 outDisplayFrame.setEmpty();
2684 return;
2685 }
2686 outDisplayFrame.set(win.mDisplayFrame);
2687 }
2688 }
2689
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002690 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2691 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002692 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2693 window.mWallpaperX = x;
2694 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002695 window.mWallpaperXStep = xStep;
2696 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002697 if (updateWallpaperOffsetLocked(window, true)) {
2698 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002699 }
2700 }
2701 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002702
Dianne Hackborn75804932009-10-20 20:15:20 -07002703 void wallpaperCommandComplete(IBinder window, Bundle result) {
2704 synchronized (mWindowMap) {
2705 if (mWaitingOnWallpaper != null &&
2706 mWaitingOnWallpaper.mClient.asBinder() == window) {
2707 mWaitingOnWallpaper = null;
2708 mWindowMap.notifyAll();
2709 }
2710 }
2711 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002712
Dianne Hackborn75804932009-10-20 20:15:20 -07002713 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2714 String action, int x, int y, int z, Bundle extras, boolean sync) {
2715 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2716 || window == mUpperWallpaperTarget) {
2717 boolean doWait = sync;
2718 int curTokenIndex = mWallpaperTokens.size();
2719 while (curTokenIndex > 0) {
2720 curTokenIndex--;
2721 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2722 int curWallpaperIndex = token.windows.size();
2723 while (curWallpaperIndex > 0) {
2724 curWallpaperIndex--;
2725 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2726 try {
2727 wallpaper.mClient.dispatchWallpaperCommand(action,
2728 x, y, z, extras, sync);
2729 // We only want to be synchronous with one wallpaper.
2730 sync = false;
2731 } catch (RemoteException e) {
2732 }
2733 }
2734 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002735
Dianne Hackborn75804932009-10-20 20:15:20 -07002736 if (doWait) {
2737 // XXX Need to wait for result.
2738 }
2739 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002740
Dianne Hackborn75804932009-10-20 20:15:20 -07002741 return null;
2742 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 public int relayoutWindow(Session session, IWindow client,
2745 WindowManager.LayoutParams attrs, int requestedWidth,
2746 int requestedHeight, int viewVisibility, boolean insetsPending,
2747 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002748 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 boolean displayed = false;
2750 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002751 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002755 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 if (win == null) {
2757 return 0;
2758 }
2759 win.mRequestedWidth = requestedWidth;
2760 win.mRequestedHeight = requestedHeight;
2761
2762 if (attrs != null) {
2763 mPolicy.adjustWindowParamsLw(attrs);
2764 }
Romain Guy06882f82009-06-10 13:36:04 -07002765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 int attrChanges = 0;
2767 int flagChanges = 0;
2768 if (attrs != null) {
2769 flagChanges = win.mAttrs.flags ^= attrs.flags;
2770 attrChanges = win.mAttrs.copyFrom(attrs);
2771 }
2772
Joe Onorato8a9b2202010-02-26 18:56:32 -08002773 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774
2775 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2776 win.mAlpha = attrs.alpha;
2777 }
2778
2779 final boolean scaledWindow =
2780 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2781
2782 if (scaledWindow) {
2783 // requested{Width|Height} Surface's physical size
2784 // attrs.{width|height} Size on screen
2785 win.mHScale = (attrs.width != requestedWidth) ?
2786 (attrs.width / (float)requestedWidth) : 1.0f;
2787 win.mVScale = (attrs.height != requestedHeight) ?
2788 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002789 } else {
2790 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 }
2792
2793 boolean imMayMove = (flagChanges&(
2794 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2795 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 boolean focusMayChange = win.mViewVisibility != viewVisibility
2798 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2799 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002800
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002801 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2802 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 win.mRelayoutCalled = true;
2805 final int oldVisibility = win.mViewVisibility;
2806 win.mViewVisibility = viewVisibility;
2807 if (viewVisibility == View.VISIBLE &&
2808 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2809 displayed = !win.isVisibleLw();
2810 if (win.mExiting) {
2811 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002812 if (win.mAnimation != null) {
2813 win.mAnimation.cancel();
2814 win.mAnimation = null;
2815 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 }
2817 if (win.mDestroying) {
2818 win.mDestroying = false;
2819 mDestroySurface.remove(win);
2820 }
2821 if (oldVisibility == View.GONE) {
2822 win.mEnterAnimationPending = true;
2823 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002824 if (displayed) {
2825 if (win.mSurface != null && !win.mDrawPending
2826 && !win.mCommitDrawPending && !mDisplayFrozen
2827 && mPolicy.isScreenOn()) {
2828 applyEnterAnimationLocked(win);
2829 }
2830 if ((win.mAttrs.flags
2831 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2832 if (DEBUG_VISIBILITY) Slog.v(TAG,
2833 "Relayout window turning screen on: " + win);
2834 win.mTurnOnScreen = true;
2835 }
2836 int diff = 0;
2837 if (win.mConfiguration != mCurConfiguration
2838 && (win.mConfiguration == null
2839 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2840 win.mConfiguration = mCurConfiguration;
2841 if (DEBUG_CONFIGURATION) {
2842 Slog.i(TAG, "Window " + win + " visible with new config: "
2843 + win.mConfiguration + " / 0x"
2844 + Integer.toHexString(diff));
2845 }
2846 outConfig.setTo(mCurConfiguration);
2847 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002849 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2850 // To change the format, we need to re-build the surface.
2851 win.destroySurfaceLocked();
2852 displayed = true;
2853 }
2854 try {
2855 Surface surface = win.createSurfaceLocked();
2856 if (surface != null) {
2857 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002858 win.mReportDestroySurface = false;
2859 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002860 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002861 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002863 // For some reason there isn't a surface. Clear the
2864 // caller's object so they see the same state.
2865 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 }
2867 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002868 mInputMonitor.updateInputWindowsLw();
2869
Joe Onorato8a9b2202010-02-26 18:56:32 -08002870 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002871 + client + " (" + win.mAttrs.getTitle() + ")",
2872 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 Binder.restoreCallingIdentity(origId);
2874 return 0;
2875 }
2876 if (displayed) {
2877 focusMayChange = true;
2878 }
2879 if (win.mAttrs.type == TYPE_INPUT_METHOD
2880 && mInputMethodWindow == null) {
2881 mInputMethodWindow = win;
2882 imMayMove = true;
2883 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002884 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2885 && win.mAppToken != null
2886 && win.mAppToken.startingWindow != null) {
2887 // Special handling of starting window over the base
2888 // window of the app: propagate lock screen flags to it,
2889 // to provide the correct semantics while starting.
2890 final int mask =
2891 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002892 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2893 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002894 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2895 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002897 } else {
2898 win.mEnterAnimationPending = false;
2899 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002900 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002901 + ": mExiting=" + win.mExiting
2902 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 // If we are not currently running the exit animation, we
2904 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002905 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 // Try starting an animation; if there isn't one, we
2907 // can destroy the surface right away.
2908 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2909 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2910 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2911 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002912 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002913 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002914 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 } else if (win.isAnimating()) {
2917 // Currently in a hide animation... turn this into
2918 // an exit.
2919 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002920 } else if (win == mWallpaperTarget) {
2921 // If the wallpaper is currently behind this
2922 // window, we need to change both of them inside
2923 // of a transaction to avoid artifacts.
2924 win.mExiting = true;
2925 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 } else {
2927 if (mInputMethodWindow == win) {
2928 mInputMethodWindow = null;
2929 }
2930 win.destroySurfaceLocked();
2931 }
2932 }
2933 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002934
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002935 if (win.mSurface == null || (win.getAttrs().flags
2936 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2937 || win.mSurfacePendingDestroy) {
2938 // We are being called from a local process, which
2939 // means outSurface holds its current surface. Ensure the
2940 // surface object is cleared, but we don't want it actually
2941 // destroyed at this point.
2942 win.mSurfacePendingDestroy = false;
2943 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002944 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002945 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002946 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002947 "Keeping surface, will report destroy: " + win);
2948 win.mReportDestroySurface = true;
2949 outSurface.copyFrom(win.mSurface);
2950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 }
2952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002953 if (focusMayChange) {
2954 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2955 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 imMayMove = false;
2957 }
2958 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2959 }
Romain Guy06882f82009-06-10 13:36:04 -07002960
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002961 // updateFocusedWindowLocked() already assigned layers so we only need to
2962 // reassign them at this point if the IM window state gets shuffled
2963 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002966 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2967 // Little hack here -- we -should- be able to rely on the
2968 // function to return true if the IME has moved and needs
2969 // its layer recomputed. However, if the IME was hidden
2970 // and isn't actually moved in the list, its layer may be
2971 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 assignLayers = true;
2973 }
2974 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002975 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002976 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002977 assignLayers = true;
2978 }
2979 }
Romain Guy06882f82009-06-10 13:36:04 -07002980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002981 mLayoutNeeded = true;
2982 win.mGivenInsetsPending = insetsPending;
2983 if (assignLayers) {
2984 assignLayersLocked();
2985 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002986 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002988 if (displayed && win.mIsWallpaper) {
2989 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002990 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 if (win.mAppToken != null) {
2993 win.mAppToken.updateReportedVisibilityLocked();
2994 }
2995 outFrame.set(win.mFrame);
2996 outContentInsets.set(win.mContentInsets);
2997 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002998 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002999 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07003000 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 + ", requestedHeight=" + requestedHeight
3002 + ", viewVisibility=" + viewVisibility
3003 + "\nRelayout returning frame=" + outFrame
3004 + ", surface=" + outSurface);
3005
Joe Onorato8a9b2202010-02-26 18:56:32 -08003006 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003007 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3008
3009 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07003010
3011 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003012 }
3013
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003014 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015 sendNewConfiguration();
3016 }
Romain Guy06882f82009-06-10 13:36:04 -07003017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
3021 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
3022 }
3023
3024 public void finishDrawingWindow(Session session, IWindow client) {
3025 final long origId = Binder.clearCallingIdentity();
3026 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003027 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003029 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3030 adjustWallpaperWindowsLocked();
3031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 mLayoutNeeded = true;
3033 performLayoutAndPlaceSurfacesLocked();
3034 }
3035 }
3036 Binder.restoreCallingIdentity(origId);
3037 }
3038
3039 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003040 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 + (lp != null ? lp.packageName : null)
3042 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3043 if (lp != null && lp.windowAnimations != 0) {
3044 // If this is a system resource, don't try to load it from the
3045 // application resources. It is nice to avoid loading application
3046 // resources if we can.
3047 String packageName = lp.packageName != null ? lp.packageName : "android";
3048 int resId = lp.windowAnimations;
3049 if ((resId&0xFF000000) == 0x01000000) {
3050 packageName = "android";
3051 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003052 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 + packageName);
3054 return AttributeCache.instance().get(packageName, resId,
3055 com.android.internal.R.styleable.WindowAnimation);
3056 }
3057 return null;
3058 }
Romain Guy06882f82009-06-10 13:36:04 -07003059
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003060 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003061 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003062 + packageName + " resId=0x" + Integer.toHexString(resId));
3063 if (packageName != null) {
3064 if ((resId&0xFF000000) == 0x01000000) {
3065 packageName = "android";
3066 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003067 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003068 + packageName);
3069 return AttributeCache.instance().get(packageName, resId,
3070 com.android.internal.R.styleable.WindowAnimation);
3071 }
3072 return null;
3073 }
3074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003075 private void applyEnterAnimationLocked(WindowState win) {
3076 int transit = WindowManagerPolicy.TRANSIT_SHOW;
3077 if (win.mEnterAnimationPending) {
3078 win.mEnterAnimationPending = false;
3079 transit = WindowManagerPolicy.TRANSIT_ENTER;
3080 }
3081
3082 applyAnimationLocked(win, transit, true);
3083 }
3084
3085 private boolean applyAnimationLocked(WindowState win,
3086 int transit, boolean isEntrance) {
3087 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3088 // If we are trying to apply an animation, but already running
3089 // an animation of the same type, then just leave that one alone.
3090 return true;
3091 }
Romain Guy06882f82009-06-10 13:36:04 -07003092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 // Only apply an animation if the display isn't frozen. If it is
3094 // frozen, there is no reason to animate and it can cause strange
3095 // artifacts when we unfreeze the display if some different animation
3096 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003097 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 int anim = mPolicy.selectAnimationLw(win, transit);
3099 int attr = -1;
3100 Animation a = null;
3101 if (anim != 0) {
3102 a = AnimationUtils.loadAnimation(mContext, anim);
3103 } else {
3104 switch (transit) {
3105 case WindowManagerPolicy.TRANSIT_ENTER:
3106 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3107 break;
3108 case WindowManagerPolicy.TRANSIT_EXIT:
3109 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3110 break;
3111 case WindowManagerPolicy.TRANSIT_SHOW:
3112 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3113 break;
3114 case WindowManagerPolicy.TRANSIT_HIDE:
3115 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3116 break;
3117 }
3118 if (attr >= 0) {
3119 a = loadAnimation(win.mAttrs, attr);
3120 }
3121 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003122 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3124 + " mAnimation=" + win.mAnimation
3125 + " isEntrance=" + isEntrance);
3126 if (a != null) {
3127 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003128 RuntimeException e = null;
3129 if (!HIDE_STACK_CRAWLS) {
3130 e = new RuntimeException();
3131 e.fillInStackTrace();
3132 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003133 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003134 }
3135 win.setAnimation(a);
3136 win.mAnimationIsEntrance = isEntrance;
3137 }
3138 } else {
3139 win.clearAnimation();
3140 }
3141
3142 return win.mAnimation != null;
3143 }
3144
3145 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3146 int anim = 0;
3147 Context context = mContext;
3148 if (animAttr >= 0) {
3149 AttributeCache.Entry ent = getCachedAnimations(lp);
3150 if (ent != null) {
3151 context = ent.context;
3152 anim = ent.array.getResourceId(animAttr, 0);
3153 }
3154 }
3155 if (anim != 0) {
3156 return AnimationUtils.loadAnimation(context, anim);
3157 }
3158 return null;
3159 }
Romain Guy06882f82009-06-10 13:36:04 -07003160
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003161 private Animation loadAnimation(String packageName, int resId) {
3162 int anim = 0;
3163 Context context = mContext;
3164 if (resId >= 0) {
3165 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3166 if (ent != null) {
3167 context = ent.context;
3168 anim = resId;
3169 }
3170 }
3171 if (anim != 0) {
3172 return AnimationUtils.loadAnimation(context, anim);
3173 }
3174 return null;
3175 }
3176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 private boolean applyAnimationLocked(AppWindowToken wtoken,
3178 WindowManager.LayoutParams lp, int transit, boolean enter) {
3179 // Only apply an animation if the display isn't frozen. If it is
3180 // frozen, there is no reason to animate and it can cause strange
3181 // artifacts when we unfreeze the display if some different animation
3182 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003183 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003184 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003185 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003186 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003187 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003188 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003189 } else if (mNextAppTransitionPackage != null) {
3190 a = loadAnimation(mNextAppTransitionPackage, enter ?
3191 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003192 } else {
3193 int animAttr = 0;
3194 switch (transit) {
3195 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3196 animAttr = enter
3197 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3198 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3199 break;
3200 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3201 animAttr = enter
3202 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3203 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3204 break;
3205 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3206 animAttr = enter
3207 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3208 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3209 break;
3210 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3211 animAttr = enter
3212 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3213 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3214 break;
3215 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3216 animAttr = enter
3217 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3218 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3219 break;
3220 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3221 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003222 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003223 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3224 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003225 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003226 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003227 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3228 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003229 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003230 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003231 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003232 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3233 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3234 break;
3235 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3236 animAttr = enter
3237 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3238 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3239 break;
3240 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3241 animAttr = enter
3242 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3243 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003244 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003245 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003246 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003247 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003248 + " anim=" + a
3249 + " animAttr=0x" + Integer.toHexString(animAttr)
3250 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003252 if (a != null) {
3253 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003254 RuntimeException e = null;
3255 if (!HIDE_STACK_CRAWLS) {
3256 e = new RuntimeException();
3257 e.fillInStackTrace();
3258 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003259 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 }
3261 wtoken.setAnimation(a);
3262 }
3263 } else {
3264 wtoken.clearAnimation();
3265 }
3266
3267 return wtoken.animation != null;
3268 }
3269
3270 // -------------------------------------------------------------
3271 // Application Window Tokens
3272 // -------------------------------------------------------------
3273
3274 public void validateAppTokens(List tokens) {
3275 int v = tokens.size()-1;
3276 int m = mAppTokens.size()-1;
3277 while (v >= 0 && m >= 0) {
3278 AppWindowToken wtoken = mAppTokens.get(m);
3279 if (wtoken.removed) {
3280 m--;
3281 continue;
3282 }
3283 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003284 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3286 }
3287 v--;
3288 m--;
3289 }
3290 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003291 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 v--;
3293 }
3294 while (m >= 0) {
3295 AppWindowToken wtoken = mAppTokens.get(m);
3296 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003297 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 }
3299 m--;
3300 }
3301 }
3302
3303 boolean checkCallingPermission(String permission, String func) {
3304 // Quick check: if the calling permission is me, it's all okay.
3305 if (Binder.getCallingPid() == Process.myPid()) {
3306 return true;
3307 }
Romain Guy06882f82009-06-10 13:36:04 -07003308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 if (mContext.checkCallingPermission(permission)
3310 == PackageManager.PERMISSION_GRANTED) {
3311 return true;
3312 }
3313 String msg = "Permission Denial: " + func + " from pid="
3314 + Binder.getCallingPid()
3315 + ", uid=" + Binder.getCallingUid()
3316 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003317 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 return false;
3319 }
Romain Guy06882f82009-06-10 13:36:04 -07003320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 AppWindowToken findAppWindowToken(IBinder token) {
3322 WindowToken wtoken = mTokenMap.get(token);
3323 if (wtoken == null) {
3324 return null;
3325 }
3326 return wtoken.appWindowToken;
3327 }
Romain Guy06882f82009-06-10 13:36:04 -07003328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 public void addWindowToken(IBinder token, int type) {
3330 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3331 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003332 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003333 }
Romain Guy06882f82009-06-10 13:36:04 -07003334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 synchronized(mWindowMap) {
3336 WindowToken wtoken = mTokenMap.get(token);
3337 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003338 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 return;
3340 }
3341 wtoken = new WindowToken(token, type, true);
3342 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003343 if (type == TYPE_WALLPAPER) {
3344 mWallpaperTokens.add(wtoken);
3345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 }
3347 }
Romain Guy06882f82009-06-10 13:36:04 -07003348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 public void removeWindowToken(IBinder token) {
3350 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3351 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003352 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 }
3354
3355 final long origId = Binder.clearCallingIdentity();
3356 synchronized(mWindowMap) {
3357 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 if (wtoken != null) {
3359 boolean delayed = false;
3360 if (!wtoken.hidden) {
3361 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003363 final int N = wtoken.windows.size();
3364 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 for (int i=0; i<N; i++) {
3367 WindowState win = wtoken.windows.get(i);
3368
3369 if (win.isAnimating()) {
3370 delayed = true;
3371 }
Romain Guy06882f82009-06-10 13:36:04 -07003372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 if (win.isVisibleNow()) {
3374 applyAnimationLocked(win,
3375 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 changed = true;
3377 }
3378 }
3379
3380 if (changed) {
3381 mLayoutNeeded = true;
3382 performLayoutAndPlaceSurfacesLocked();
3383 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3384 }
Romain Guy06882f82009-06-10 13:36:04 -07003385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 if (delayed) {
3387 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003388 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3389 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 }
3391 }
Romain Guy06882f82009-06-10 13:36:04 -07003392
Jeff Brownc5ed5912010-07-14 18:48:53 -07003393 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003395 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 }
3397 }
3398 Binder.restoreCallingIdentity(origId);
3399 }
3400
3401 public void addAppToken(int addPos, IApplicationToken token,
3402 int groupId, int requestedOrientation, boolean fullscreen) {
3403 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3404 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003405 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 }
Jeff Brown349703e2010-06-22 01:27:15 -07003407
3408 // Get the dispatching timeout here while we are not holding any locks so that it
3409 // can be cached by the AppWindowToken. The timeout value is used later by the
3410 // input dispatcher in code that does hold locks. If we did not cache the value
3411 // here we would run the chance of introducing a deadlock between the window manager
3412 // (which holds locks while updating the input dispatcher state) and the activity manager
3413 // (which holds locks while querying the application token).
3414 long inputDispatchingTimeoutNanos;
3415 try {
3416 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3417 } catch (RemoteException ex) {
3418 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3419 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3420 }
Romain Guy06882f82009-06-10 13:36:04 -07003421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003422 synchronized(mWindowMap) {
3423 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3424 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003425 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 return;
3427 }
3428 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003429 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 wtoken.groupId = groupId;
3431 wtoken.appFullscreen = fullscreen;
3432 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003433 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 // Application tokens start out hidden.
3438 wtoken.hidden = true;
3439 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 //dump();
3442 }
3443 }
Romain Guy06882f82009-06-10 13:36:04 -07003444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 public void setAppGroupId(IBinder token, int groupId) {
3446 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3447 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003448 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 }
3450
3451 synchronized(mWindowMap) {
3452 AppWindowToken wtoken = findAppWindowToken(token);
3453 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003454 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 return;
3456 }
3457 wtoken.groupId = groupId;
3458 }
3459 }
Romain Guy06882f82009-06-10 13:36:04 -07003460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 public int getOrientationFromWindowsLocked() {
3462 int pos = mWindows.size() - 1;
3463 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003464 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 pos--;
3466 if (wtoken.mAppToken != null) {
3467 // We hit an application window. so the orientation will be determined by the
3468 // app window. No point in continuing further.
3469 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3470 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003471 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003472 continue;
3473 }
3474 int req = wtoken.mAttrs.screenOrientation;
3475 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3476 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3477 continue;
3478 } else {
3479 return req;
3480 }
3481 }
3482 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3483 }
Romain Guy06882f82009-06-10 13:36:04 -07003484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003485 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003486 int pos = mAppTokens.size() - 1;
3487 int curGroup = 0;
3488 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3489 boolean findingBehind = false;
3490 boolean haveGroup = false;
3491 boolean lastFullscreen = false;
3492 while (pos >= 0) {
3493 AppWindowToken wtoken = mAppTokens.get(pos);
3494 pos--;
3495 // if we're about to tear down this window and not seek for
3496 // the behind activity, don't use it for orientation
3497 if (!findingBehind
3498 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3499 continue;
3500 }
3501
3502 if (!haveGroup) {
3503 // We ignore any hidden applications on the top.
3504 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003505 continue;
3506 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003507 haveGroup = true;
3508 curGroup = wtoken.groupId;
3509 lastOrientation = wtoken.requestedOrientation;
3510 } else if (curGroup != wtoken.groupId) {
3511 // If we have hit a new application group, and the bottom
3512 // of the previous group didn't explicitly say to use
3513 // the orientation behind it, and the last app was
3514 // full screen, then we'll stick with the
3515 // user's orientation.
3516 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3517 && lastFullscreen) {
3518 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003521 int or = wtoken.requestedOrientation;
3522 // If this application is fullscreen, and didn't explicitly say
3523 // to use the orientation behind it, then just take whatever
3524 // orientation it has and ignores whatever is under it.
3525 lastFullscreen = wtoken.appFullscreen;
3526 if (lastFullscreen
3527 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3528 return or;
3529 }
3530 // If this application has requested an explicit orientation,
3531 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003532 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3533 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003534 return or;
3535 }
3536 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3537 }
3538 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003539 }
Romain Guy06882f82009-06-10 13:36:04 -07003540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003542 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003543 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3544 "updateOrientationFromAppTokens()")) {
3545 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3546 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003547
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003548 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003550
3551 synchronized(mWindowMap) {
3552 if (updateOrientationFromAppTokensLocked()) {
3553 if (freezeThisOneIfNeeded != null) {
3554 AppWindowToken wtoken = findAppWindowToken(
3555 freezeThisOneIfNeeded);
3556 if (wtoken != null) {
3557 startAppFreezingScreenLocked(wtoken,
3558 ActivityInfo.CONFIG_ORIENTATION);
3559 }
3560 }
3561 config = computeNewConfigurationLocked();
3562
3563 } else if (currentConfig != null) {
3564 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003565 // state mismatches the activity manager's, update it,
3566 // disregarding font scale, which should remain set to
3567 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003568 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003569 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003570 if (computeNewConfigurationLocked(mTempConfiguration)) {
3571 if (currentConfig.diff(mTempConfiguration) != 0) {
3572 mWaitingForConfig = true;
3573 mLayoutNeeded = true;
3574 startFreezingDisplayLocked();
3575 config = new Configuration(mTempConfiguration);
3576 }
3577 }
3578 }
3579 }
3580
Dianne Hackborncfaef692009-06-15 14:24:44 -07003581 Binder.restoreCallingIdentity(ident);
3582 return config;
3583 }
3584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003586 * Determine the new desired orientation of the display, returning
3587 * a non-null new Configuration if it has changed from the current
3588 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3589 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3590 * SCREEN. This will typically be done for you if you call
3591 * sendNewConfiguration().
3592 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 * The orientation is computed from non-application windows first. If none of
3594 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003595 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003596 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3597 * android.os.IBinder)
3598 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003599 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003600 if (mDisplayFrozen) {
3601 // If the display is frozen, some activities may be in the middle
3602 // of restarting, and thus have removed their old window. If the
3603 // window has the flag to hide the lock screen, then the lock screen
3604 // can re-appear and inflict its own orientation on us. Keep the
3605 // orientation stable until this all settles down.
3606 return false;
3607 }
3608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 long ident = Binder.clearCallingIdentity();
3611 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003612 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 mForcedAppOrientation = req;
3616 //send a message to Policy indicating orientation change to take
3617 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003618 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003619 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3620 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3621 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 }
3623 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003624
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003625 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 } finally {
3627 Binder.restoreCallingIdentity(ident);
3628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 }
Romain Guy06882f82009-06-10 13:36:04 -07003630
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003631 int computeForcedAppOrientationLocked() {
3632 int req = getOrientationFromWindowsLocked();
3633 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3634 req = getOrientationFromAppTokensLocked();
3635 }
3636 return req;
3637 }
Romain Guy06882f82009-06-10 13:36:04 -07003638
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003639 public void setNewConfiguration(Configuration config) {
3640 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3641 "setNewConfiguration()")) {
3642 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3643 }
3644
3645 synchronized(mWindowMap) {
3646 mCurConfiguration = new Configuration(config);
3647 mWaitingForConfig = false;
3648 performLayoutAndPlaceSurfacesLocked();
3649 }
3650 }
3651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3653 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3654 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003655 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 }
Romain Guy06882f82009-06-10 13:36:04 -07003657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 synchronized(mWindowMap) {
3659 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3660 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003661 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 return;
3663 }
Romain Guy06882f82009-06-10 13:36:04 -07003664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 wtoken.requestedOrientation = requestedOrientation;
3666 }
3667 }
Romain Guy06882f82009-06-10 13:36:04 -07003668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 public int getAppOrientation(IApplicationToken token) {
3670 synchronized(mWindowMap) {
3671 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3672 if (wtoken == null) {
3673 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3674 }
Romain Guy06882f82009-06-10 13:36:04 -07003675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 return wtoken.requestedOrientation;
3677 }
3678 }
Romain Guy06882f82009-06-10 13:36:04 -07003679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3681 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3682 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003683 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685
3686 synchronized(mWindowMap) {
3687 boolean changed = false;
3688 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003689 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 changed = mFocusedApp != null;
3691 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003692 if (changed) {
3693 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003695 } else {
3696 AppWindowToken newFocus = findAppWindowToken(token);
3697 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003698 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 return;
3700 }
3701 changed = mFocusedApp != newFocus;
3702 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003703 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003704 if (changed) {
3705 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 }
3708
3709 if (moveFocusNow && changed) {
3710 final long origId = Binder.clearCallingIdentity();
3711 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3712 Binder.restoreCallingIdentity(origId);
3713 }
3714 }
3715 }
3716
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003717 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3719 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003720 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 }
Romain Guy06882f82009-06-10 13:36:04 -07003722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003724 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 TAG, "Prepare app transition: transit=" + transit
3726 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003727 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003728 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3729 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003731 } else if (!alwaysKeepCurrent) {
3732 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3733 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3734 // Opening a new task always supersedes a close for the anim.
3735 mNextAppTransition = transit;
3736 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3737 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3738 // Opening a new activity always supersedes a close for the anim.
3739 mNextAppTransition = transit;
3740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 }
3742 mAppTransitionReady = false;
3743 mAppTransitionTimeout = false;
3744 mStartingIconInTransition = false;
3745 mSkipAppTransitionAnimation = false;
3746 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3747 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3748 5000);
3749 }
3750 }
3751 }
3752
3753 public int getPendingAppTransition() {
3754 return mNextAppTransition;
3755 }
Romain Guy06882f82009-06-10 13:36:04 -07003756
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003757 public void overridePendingAppTransition(String packageName,
3758 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003759 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003760 mNextAppTransitionPackage = packageName;
3761 mNextAppTransitionEnter = enterAnim;
3762 mNextAppTransitionExit = exitAnim;
3763 }
3764 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 public void executeAppTransition() {
3767 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3768 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003769 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 }
Romain Guy06882f82009-06-10 13:36:04 -07003771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003773 if (DEBUG_APP_TRANSITIONS) {
3774 RuntimeException e = new RuntimeException("here");
3775 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003776 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003777 + mNextAppTransition, e);
3778 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003779 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 mAppTransitionReady = true;
3781 final long origId = Binder.clearCallingIdentity();
3782 performLayoutAndPlaceSurfacesLocked();
3783 Binder.restoreCallingIdentity(origId);
3784 }
3785 }
3786 }
3787
3788 public void setAppStartingWindow(IBinder token, String pkg,
3789 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003790 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3792 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003793 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
3795
3796 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003797 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3799 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003801 AppWindowToken wtoken = findAppWindowToken(token);
3802 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003803 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 return;
3805 }
3806
3807 // If the display is frozen, we won't do anything until the
3808 // actual window is displayed so there is no reason to put in
3809 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003810 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003811 return;
3812 }
Romain Guy06882f82009-06-10 13:36:04 -07003813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 if (wtoken.startingData != null) {
3815 return;
3816 }
Romain Guy06882f82009-06-10 13:36:04 -07003817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 if (transferFrom != null) {
3819 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3820 if (ttoken != null) {
3821 WindowState startingWindow = ttoken.startingWindow;
3822 if (startingWindow != null) {
3823 if (mStartingIconInTransition) {
3824 // In this case, the starting icon has already
3825 // been displayed, so start letting windows get
3826 // shown immediately without any more transitions.
3827 mSkipAppTransitionAnimation = true;
3828 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003829 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 "Moving existing starting from " + ttoken
3831 + " to " + wtoken);
3832 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 // Transfer the starting window over to the new
3835 // token.
3836 wtoken.startingData = ttoken.startingData;
3837 wtoken.startingView = ttoken.startingView;
3838 wtoken.startingWindow = startingWindow;
3839 ttoken.startingData = null;
3840 ttoken.startingView = null;
3841 ttoken.startingWindow = null;
3842 ttoken.startingMoved = true;
3843 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003844 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003846 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003847 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003848 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003849 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003850 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3851 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 ttoken.windows.remove(startingWindow);
3853 ttoken.allAppWindows.remove(startingWindow);
3854 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003856 // Propagate other interesting state between the
3857 // tokens. If the old token is displayed, we should
3858 // immediately force the new one to be displayed. If
3859 // it is animating, we need to move that animation to
3860 // the new one.
3861 if (ttoken.allDrawn) {
3862 wtoken.allDrawn = true;
3863 }
3864 if (ttoken.firstWindowDrawn) {
3865 wtoken.firstWindowDrawn = true;
3866 }
3867 if (!ttoken.hidden) {
3868 wtoken.hidden = false;
3869 wtoken.hiddenRequested = false;
3870 wtoken.willBeHidden = false;
3871 }
3872 if (wtoken.clientHidden != ttoken.clientHidden) {
3873 wtoken.clientHidden = ttoken.clientHidden;
3874 wtoken.sendAppVisibilityToClients();
3875 }
3876 if (ttoken.animation != null) {
3877 wtoken.animation = ttoken.animation;
3878 wtoken.animating = ttoken.animating;
3879 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3880 ttoken.animation = null;
3881 ttoken.animLayerAdjustment = 0;
3882 wtoken.updateLayers();
3883 ttoken.updateLayers();
3884 }
Romain Guy06882f82009-06-10 13:36:04 -07003885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003887 mLayoutNeeded = true;
3888 performLayoutAndPlaceSurfacesLocked();
3889 Binder.restoreCallingIdentity(origId);
3890 return;
3891 } else if (ttoken.startingData != null) {
3892 // The previous app was getting ready to show a
3893 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003894 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 "Moving pending starting from " + ttoken
3896 + " to " + wtoken);
3897 wtoken.startingData = ttoken.startingData;
3898 ttoken.startingData = null;
3899 ttoken.startingMoved = true;
3900 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3901 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3902 // want to process the message ASAP, before any other queued
3903 // messages.
3904 mH.sendMessageAtFrontOfQueue(m);
3905 return;
3906 }
3907 }
3908 }
3909
3910 // There is no existing starting window, and the caller doesn't
3911 // want us to create one, so that's it!
3912 if (!createIfNeeded) {
3913 return;
3914 }
Romain Guy06882f82009-06-10 13:36:04 -07003915
Dianne Hackborn284ac932009-08-28 10:34:25 -07003916 // If this is a translucent or wallpaper window, then don't
3917 // show a starting window -- the current effect (a full-screen
3918 // opaque starting window that fades away to the real contents
3919 // when it is ready) does not work for this.
3920 if (theme != 0) {
3921 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3922 com.android.internal.R.styleable.Window);
3923 if (ent.array.getBoolean(
3924 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3925 return;
3926 }
3927 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003928 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3929 return;
3930 }
3931 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003932 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3933 return;
3934 }
3935 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 mStartingIconInTransition = true;
3938 wtoken.startingData = new StartingData(
3939 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003940 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3942 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3943 // want to process the message ASAP, before any other queued
3944 // messages.
3945 mH.sendMessageAtFrontOfQueue(m);
3946 }
3947 }
3948
3949 public void setAppWillBeHidden(IBinder token) {
3950 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3951 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003952 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 }
3954
3955 AppWindowToken wtoken;
3956
3957 synchronized(mWindowMap) {
3958 wtoken = findAppWindowToken(token);
3959 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003960 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 -08003961 return;
3962 }
3963 wtoken.willBeHidden = true;
3964 }
3965 }
Romain Guy06882f82009-06-10 13:36:04 -07003966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3968 boolean visible, int transit, boolean performLayout) {
3969 boolean delayed = false;
3970
3971 if (wtoken.clientHidden == visible) {
3972 wtoken.clientHidden = !visible;
3973 wtoken.sendAppVisibilityToClients();
3974 }
Romain Guy06882f82009-06-10 13:36:04 -07003975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 wtoken.willBeHidden = false;
3977 if (wtoken.hidden == visible) {
3978 final int N = wtoken.allAppWindows.size();
3979 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003980 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3982 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003985
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003986 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003987 if (wtoken.animation == sDummyAnimation) {
3988 wtoken.animation = null;
3989 }
3990 applyAnimationLocked(wtoken, lp, transit, visible);
3991 changed = true;
3992 if (wtoken.animation != null) {
3993 delayed = runningAppAnimation = true;
3994 }
3995 }
Romain Guy06882f82009-06-10 13:36:04 -07003996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 for (int i=0; i<N; i++) {
3998 WindowState win = wtoken.allAppWindows.get(i);
3999 if (win == wtoken.startingWindow) {
4000 continue;
4001 }
4002
4003 if (win.isAnimating()) {
4004 delayed = true;
4005 }
Romain Guy06882f82009-06-10 13:36:04 -07004006
Joe Onorato8a9b2202010-02-26 18:56:32 -08004007 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004008 //win.dump(" ");
4009 if (visible) {
4010 if (!win.isVisibleNow()) {
4011 if (!runningAppAnimation) {
4012 applyAnimationLocked(win,
4013 WindowManagerPolicy.TRANSIT_ENTER, true);
4014 }
4015 changed = true;
4016 }
4017 } else if (win.isVisibleNow()) {
4018 if (!runningAppAnimation) {
4019 applyAnimationLocked(win,
4020 WindowManagerPolicy.TRANSIT_EXIT, false);
4021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 changed = true;
4023 }
4024 }
4025
4026 wtoken.hidden = wtoken.hiddenRequested = !visible;
4027 if (!visible) {
4028 unsetAppFreezingScreenLocked(wtoken, true, true);
4029 } else {
4030 // If we are being set visible, and the starting window is
4031 // not yet displayed, then make sure it doesn't get displayed.
4032 WindowState swin = wtoken.startingWindow;
4033 if (swin != null && (swin.mDrawPending
4034 || swin.mCommitDrawPending)) {
4035 swin.mPolicyVisibility = false;
4036 swin.mPolicyVisibilityAfterAnim = false;
4037 }
4038 }
Romain Guy06882f82009-06-10 13:36:04 -07004039
Joe Onorato8a9b2202010-02-26 18:56:32 -08004040 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4042 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004043
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004044 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004046 if (performLayout) {
4047 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
4048 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07004049 } else {
4050 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
4053 }
4054
4055 if (wtoken.animation != null) {
4056 delayed = true;
4057 }
Romain Guy06882f82009-06-10 13:36:04 -07004058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059 return delayed;
4060 }
4061
4062 public void setAppVisibility(IBinder token, boolean visible) {
4063 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4064 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004065 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 }
4067
4068 AppWindowToken wtoken;
4069
4070 synchronized(mWindowMap) {
4071 wtoken = findAppWindowToken(token);
4072 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004073 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 return;
4075 }
4076
4077 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004078 RuntimeException e = null;
4079 if (!HIDE_STACK_CRAWLS) {
4080 e = new RuntimeException();
4081 e.fillInStackTrace();
4082 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004083 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 + "): mNextAppTransition=" + mNextAppTransition
4085 + " hidden=" + wtoken.hidden
4086 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4087 }
Romain Guy06882f82009-06-10 13:36:04 -07004088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 // If we are preparing an app transition, then delay changing
4090 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004091 if (!mDisplayFrozen && mPolicy.isScreenOn()
4092 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 // Already in requested state, don't do anything more.
4094 if (wtoken.hiddenRequested != visible) {
4095 return;
4096 }
4097 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004098
Joe Onorato8a9b2202010-02-26 18:56:32 -08004099 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 TAG, "Setting dummy animation on: " + wtoken);
4101 wtoken.setDummyAnimation();
4102 mOpeningApps.remove(wtoken);
4103 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004104 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 wtoken.inPendingTransaction = true;
4106 if (visible) {
4107 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 wtoken.startingDisplayed = false;
4109 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004110
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004111 // If the token is currently hidden (should be the
4112 // common case), then we need to set up to wait for
4113 // its windows to be ready.
4114 if (wtoken.hidden) {
4115 wtoken.allDrawn = false;
4116 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004117
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004118 if (wtoken.clientHidden) {
4119 // In the case where we are making an app visible
4120 // but holding off for a transition, we still need
4121 // to tell the client to make its windows visible so
4122 // they get drawn. Otherwise, we will wait on
4123 // performing the transition until all windows have
4124 // been drawn, they never will be, and we are sad.
4125 wtoken.clientHidden = false;
4126 wtoken.sendAppVisibilityToClients();
4127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
4129 } else {
4130 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004131
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004132 // If the token is currently visible (should be the
4133 // common case), then set up to wait for it to be hidden.
4134 if (!wtoken.hidden) {
4135 wtoken.waitingToHide = true;
4136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 }
4138 return;
4139 }
Romain Guy06882f82009-06-10 13:36:04 -07004140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004142 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 wtoken.updateReportedVisibilityLocked();
4144 Binder.restoreCallingIdentity(origId);
4145 }
4146 }
4147
4148 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4149 boolean unfreezeSurfaceNow, boolean force) {
4150 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004151 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 + " force=" + force);
4153 final int N = wtoken.allAppWindows.size();
4154 boolean unfrozeWindows = false;
4155 for (int i=0; i<N; i++) {
4156 WindowState w = wtoken.allAppWindows.get(i);
4157 if (w.mAppFreezing) {
4158 w.mAppFreezing = false;
4159 if (w.mSurface != null && !w.mOrientationChanging) {
4160 w.mOrientationChanging = true;
4161 }
4162 unfrozeWindows = true;
4163 }
4164 }
4165 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004166 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004167 wtoken.freezingScreen = false;
4168 mAppsFreezingScreen--;
4169 }
4170 if (unfreezeSurfaceNow) {
4171 if (unfrozeWindows) {
4172 mLayoutNeeded = true;
4173 performLayoutAndPlaceSurfacesLocked();
4174 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004175 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
4177 }
4178 }
Romain Guy06882f82009-06-10 13:36:04 -07004179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4181 int configChanges) {
4182 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004183 RuntimeException e = null;
4184 if (!HIDE_STACK_CRAWLS) {
4185 e = new RuntimeException();
4186 e.fillInStackTrace();
4187 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004188 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 + ": hidden=" + wtoken.hidden + " freezing="
4190 + wtoken.freezingScreen, e);
4191 }
4192 if (!wtoken.hiddenRequested) {
4193 if (!wtoken.freezingScreen) {
4194 wtoken.freezingScreen = true;
4195 mAppsFreezingScreen++;
4196 if (mAppsFreezingScreen == 1) {
4197 startFreezingDisplayLocked();
4198 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4199 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4200 5000);
4201 }
4202 }
4203 final int N = wtoken.allAppWindows.size();
4204 for (int i=0; i<N; i++) {
4205 WindowState w = wtoken.allAppWindows.get(i);
4206 w.mAppFreezing = true;
4207 }
4208 }
4209 }
Romain Guy06882f82009-06-10 13:36:04 -07004210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004211 public void startAppFreezingScreen(IBinder token, int configChanges) {
4212 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4213 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004214 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 }
4216
4217 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004218 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004219 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 return;
4221 }
Romain Guy06882f82009-06-10 13:36:04 -07004222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 AppWindowToken wtoken = findAppWindowToken(token);
4224 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004225 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 return;
4227 }
4228 final long origId = Binder.clearCallingIdentity();
4229 startAppFreezingScreenLocked(wtoken, configChanges);
4230 Binder.restoreCallingIdentity(origId);
4231 }
4232 }
Romain Guy06882f82009-06-10 13:36:04 -07004233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 public void stopAppFreezingScreen(IBinder token, boolean force) {
4235 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4236 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004237 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 }
4239
4240 synchronized(mWindowMap) {
4241 AppWindowToken wtoken = findAppWindowToken(token);
4242 if (wtoken == null || wtoken.appToken == null) {
4243 return;
4244 }
4245 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004246 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4248 unsetAppFreezingScreenLocked(wtoken, true, force);
4249 Binder.restoreCallingIdentity(origId);
4250 }
4251 }
Romain Guy06882f82009-06-10 13:36:04 -07004252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 public void removeAppToken(IBinder token) {
4254 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4255 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004256 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 }
4258
4259 AppWindowToken wtoken = null;
4260 AppWindowToken startingToken = null;
4261 boolean delayed = false;
4262
4263 final long origId = Binder.clearCallingIdentity();
4264 synchronized(mWindowMap) {
4265 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004267 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004268 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 wtoken.inPendingTransaction = false;
4270 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004271 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 if (mClosingApps.contains(wtoken)) {
4273 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004274 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004276 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 delayed = true;
4278 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004279 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004280 TAG, "Removing app " + wtoken + " delayed=" + delayed
4281 + " animation=" + wtoken.animation
4282 + " animating=" + wtoken.animating);
4283 if (delayed) {
4284 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004285 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4286 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004288 } else {
4289 // Make sure there is no animation running on this token,
4290 // so any windows associated with it will be removed as
4291 // soon as their animations are complete
4292 wtoken.animation = null;
4293 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004295 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4296 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 mAppTokens.remove(wtoken);
4298 wtoken.removed = true;
4299 if (wtoken.startingData != null) {
4300 startingToken = wtoken;
4301 }
4302 unsetAppFreezingScreenLocked(wtoken, true, true);
4303 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004304 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004305 mFocusedApp = null;
4306 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004307 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 }
4309 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004310 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004311 }
Romain Guy06882f82009-06-10 13:36:04 -07004312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 if (!delayed && wtoken != null) {
4314 wtoken.updateReportedVisibilityLocked();
4315 }
4316 }
4317 Binder.restoreCallingIdentity(origId);
4318
4319 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004320 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 + startingToken + ": app token removed");
4322 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4323 mH.sendMessage(m);
4324 }
4325 }
4326
4327 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4328 final int NW = token.windows.size();
4329 for (int i=0; i<NW; i++) {
4330 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004331 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004333 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004334 int j = win.mChildWindows.size();
4335 while (j > 0) {
4336 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004337 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004338 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004339 "Tmp removing child window " + cwin);
4340 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 }
4342 }
4343 return NW > 0;
4344 }
4345
4346 void dumpAppTokensLocked() {
4347 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004348 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 }
4350 }
Romain Guy06882f82009-06-10 13:36:04 -07004351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 void dumpWindowsLocked() {
4353 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004354 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 }
4356 }
Romain Guy06882f82009-06-10 13:36:04 -07004357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 private int findWindowOffsetLocked(int tokenPos) {
4359 final int NW = mWindows.size();
4360
4361 if (tokenPos >= mAppTokens.size()) {
4362 int i = NW;
4363 while (i > 0) {
4364 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004365 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 if (win.getAppToken() != null) {
4367 return i+1;
4368 }
4369 }
4370 }
4371
4372 while (tokenPos > 0) {
4373 // Find the first app token below the new position that has
4374 // a window displayed.
4375 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004376 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004378 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004379 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004380 "Skipping token -- currently sending to bottom");
4381 tokenPos--;
4382 continue;
4383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 int i = wtoken.windows.size();
4385 while (i > 0) {
4386 i--;
4387 WindowState win = wtoken.windows.get(i);
4388 int j = win.mChildWindows.size();
4389 while (j > 0) {
4390 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004391 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004392 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 for (int pos=NW-1; pos>=0; pos--) {
4394 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004395 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 "Found child win @" + (pos+1));
4397 return pos+1;
4398 }
4399 }
4400 }
4401 }
4402 for (int pos=NW-1; pos>=0; pos--) {
4403 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004404 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 return pos+1;
4406 }
4407 }
4408 }
4409 tokenPos--;
4410 }
4411
4412 return 0;
4413 }
4414
4415 private final int reAddWindowLocked(int index, WindowState win) {
4416 final int NCW = win.mChildWindows.size();
4417 boolean added = false;
4418 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004419 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004421 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004422 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004423 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 mWindows.add(index, win);
4425 index++;
4426 added = true;
4427 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004428 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004429 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004430 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 mWindows.add(index, cwin);
4432 index++;
4433 }
4434 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004435 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004436 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004437 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 mWindows.add(index, win);
4439 index++;
4440 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004441 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 return index;
4443 }
Romain Guy06882f82009-06-10 13:36:04 -07004444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004445 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4446 final int NW = token.windows.size();
4447 for (int i=0; i<NW; i++) {
4448 index = reAddWindowLocked(index, token.windows.get(i));
4449 }
4450 return index;
4451 }
4452
4453 public void moveAppToken(int index, IBinder token) {
4454 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4455 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004456 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004457 }
4458
4459 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004460 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 if (DEBUG_REORDER) dumpAppTokensLocked();
4462 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004463 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4464 "Start moving token " + wtoken + " initially at "
4465 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004467 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 + token + " (" + wtoken + ")");
4469 return;
4470 }
4471 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004472 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004473 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004477 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 if (DEBUG_REORDER) dumpWindowsLocked();
4479 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004480 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 if (DEBUG_REORDER) dumpWindowsLocked();
4482 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004483 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 if (DEBUG_REORDER) dumpWindowsLocked();
4485 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 mLayoutNeeded = true;
4487 performLayoutAndPlaceSurfacesLocked();
4488 }
4489 Binder.restoreCallingIdentity(origId);
4490 }
4491 }
4492
4493 private void removeAppTokensLocked(List<IBinder> tokens) {
4494 // XXX This should be done more efficiently!
4495 // (take advantage of the fact that both lists should be
4496 // ordered in the same way.)
4497 int N = tokens.size();
4498 for (int i=0; i<N; i++) {
4499 IBinder token = tokens.get(i);
4500 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004501 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4502 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004504 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 + token + " (" + wtoken + ")");
4506 i--;
4507 N--;
4508 }
4509 }
4510 }
4511
Dianne Hackborna8f60182009-09-01 19:01:50 -07004512 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4513 boolean updateFocusAndLayout) {
4514 // First remove all of the windows from the list.
4515 tmpRemoveAppWindowsLocked(wtoken);
4516
4517 // Where to start adding?
4518 int pos = findWindowOffsetLocked(tokenPos);
4519
4520 // And now add them back at the correct place.
4521 pos = reAddAppWindowsLocked(pos, wtoken);
4522
4523 if (updateFocusAndLayout) {
4524 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4525 assignLayersLocked();
4526 }
4527 mLayoutNeeded = true;
4528 performLayoutAndPlaceSurfacesLocked();
4529 }
4530 }
4531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4533 // First remove all of the windows from the list.
4534 final int N = tokens.size();
4535 int i;
4536 for (i=0; i<N; i++) {
4537 WindowToken token = mTokenMap.get(tokens.get(i));
4538 if (token != null) {
4539 tmpRemoveAppWindowsLocked(token);
4540 }
4541 }
4542
4543 // Where to start adding?
4544 int pos = findWindowOffsetLocked(tokenPos);
4545
4546 // And now add them back at the correct place.
4547 for (i=0; i<N; i++) {
4548 WindowToken token = mTokenMap.get(tokens.get(i));
4549 if (token != null) {
4550 pos = reAddAppWindowsLocked(pos, token);
4551 }
4552 }
4553
Dianne Hackborna8f60182009-09-01 19:01:50 -07004554 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4555 assignLayersLocked();
4556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 mLayoutNeeded = true;
4558 performLayoutAndPlaceSurfacesLocked();
4559
4560 //dump();
4561 }
4562
4563 public void moveAppTokensToTop(List<IBinder> tokens) {
4564 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4565 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004566 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 }
4568
4569 final long origId = Binder.clearCallingIdentity();
4570 synchronized(mWindowMap) {
4571 removeAppTokensLocked(tokens);
4572 final int N = tokens.size();
4573 for (int i=0; i<N; i++) {
4574 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4575 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004576 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4577 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004579 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004580 mToTopApps.remove(wt);
4581 mToBottomApps.remove(wt);
4582 mToTopApps.add(wt);
4583 wt.sendingToBottom = false;
4584 wt.sendingToTop = true;
4585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 }
4587 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004588
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004589 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004590 moveAppWindowsLocked(tokens, mAppTokens.size());
4591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 }
4593 Binder.restoreCallingIdentity(origId);
4594 }
4595
4596 public void moveAppTokensToBottom(List<IBinder> tokens) {
4597 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4598 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004599 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
4601
4602 final long origId = Binder.clearCallingIdentity();
4603 synchronized(mWindowMap) {
4604 removeAppTokensLocked(tokens);
4605 final int N = tokens.size();
4606 int pos = 0;
4607 for (int i=0; i<N; i++) {
4608 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4609 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004610 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4611 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004613 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004614 mToTopApps.remove(wt);
4615 mToBottomApps.remove(wt);
4616 mToBottomApps.add(i, wt);
4617 wt.sendingToTop = false;
4618 wt.sendingToBottom = true;
4619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 pos++;
4621 }
4622 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004623
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004624 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004625 moveAppWindowsLocked(tokens, 0);
4626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 }
4628 Binder.restoreCallingIdentity(origId);
4629 }
4630
4631 // -------------------------------------------------------------
4632 // Misc IWindowSession methods
4633 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004634
Jim Miller284b62e2010-06-08 14:27:42 -07004635 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004636 {
Jim Miller284b62e2010-06-08 14:27:42 -07004637 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4638 // called before DevicePolicyManagerService has started.
4639 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4640 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4641 Context.DEVICE_POLICY_SERVICE);
4642 if (dpm != null) {
4643 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4644 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4645 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4646 }
Jim Millerd6b57052010-06-07 17:52:42 -07004647 }
Jim Miller284b62e2010-06-08 14:27:42 -07004648 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004649 }
4650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004652 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 != PackageManager.PERMISSION_GRANTED) {
4654 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4655 }
Jim Millerd6b57052010-06-07 17:52:42 -07004656
Jim Miller284b62e2010-06-08 14:27:42 -07004657 synchronized (mKeyguardTokenWatcher) {
4658 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 }
4661
4662 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004663 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 != PackageManager.PERMISSION_GRANTED) {
4665 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667
Jim Miller284b62e2010-06-08 14:27:42 -07004668 synchronized (mKeyguardTokenWatcher) {
4669 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004670
Jim Miller284b62e2010-06-08 14:27:42 -07004671 if (!mKeyguardTokenWatcher.isAcquired()) {
4672 // If we are the last one to reenable the keyguard wait until
4673 // we have actually finished reenabling until returning.
4674 // It is possible that reenableKeyguard() can be called before
4675 // the previous disableKeyguard() is handled, in which case
4676 // neither mKeyguardTokenWatcher.acquired() or released() would
4677 // be called. In that case mKeyguardDisabled will be false here
4678 // and we have nothing to wait for.
4679 while (mKeyguardDisabled) {
4680 try {
4681 mKeyguardTokenWatcher.wait();
4682 } catch (InterruptedException e) {
4683 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 }
4685 }
4686 }
4687 }
4688 }
4689
4690 /**
4691 * @see android.app.KeyguardManager#exitKeyguardSecurely
4692 */
4693 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004694 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 != PackageManager.PERMISSION_GRANTED) {
4696 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4697 }
4698 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4699 public void onKeyguardExitResult(boolean success) {
4700 try {
4701 callback.onKeyguardExitResult(success);
4702 } catch (RemoteException e) {
4703 // Client has died, we don't care.
4704 }
4705 }
4706 });
4707 }
4708
4709 public boolean inKeyguardRestrictedInputMode() {
4710 return mPolicy.inKeyguardRestrictedKeyInputMode();
4711 }
Romain Guy06882f82009-06-10 13:36:04 -07004712
Dianne Hackbornffa42482009-09-23 22:20:11 -07004713 public void closeSystemDialogs(String reason) {
4714 synchronized(mWindowMap) {
4715 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004716 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004717 if (w.mSurface != null) {
4718 try {
4719 w.mClient.closeSystemDialogs(reason);
4720 } catch (RemoteException e) {
4721 }
4722 }
4723 }
4724 }
4725 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 static float fixScale(float scale) {
4728 if (scale < 0) scale = 0;
4729 else if (scale > 20) scale = 20;
4730 return Math.abs(scale);
4731 }
Romain Guy06882f82009-06-10 13:36:04 -07004732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 public void setAnimationScale(int which, float scale) {
4734 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4735 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004736 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 }
4738
4739 if (scale < 0) scale = 0;
4740 else if (scale > 20) scale = 20;
4741 scale = Math.abs(scale);
4742 switch (which) {
4743 case 0: mWindowAnimationScale = fixScale(scale); break;
4744 case 1: mTransitionAnimationScale = fixScale(scale); break;
4745 }
Romain Guy06882f82009-06-10 13:36:04 -07004746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 // Persist setting
4748 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4749 }
Romain Guy06882f82009-06-10 13:36:04 -07004750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 public void setAnimationScales(float[] scales) {
4752 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4753 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004754 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 }
4756
4757 if (scales != null) {
4758 if (scales.length >= 1) {
4759 mWindowAnimationScale = fixScale(scales[0]);
4760 }
4761 if (scales.length >= 2) {
4762 mTransitionAnimationScale = fixScale(scales[1]);
4763 }
4764 }
Romain Guy06882f82009-06-10 13:36:04 -07004765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004766 // Persist setting
4767 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4768 }
Romain Guy06882f82009-06-10 13:36:04 -07004769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 public float getAnimationScale(int which) {
4771 switch (which) {
4772 case 0: return mWindowAnimationScale;
4773 case 1: return mTransitionAnimationScale;
4774 }
4775 return 0;
4776 }
Romain Guy06882f82009-06-10 13:36:04 -07004777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 public float[] getAnimationScales() {
4779 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4780 }
Romain Guy06882f82009-06-10 13:36:04 -07004781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004782 public int getSwitchState(int sw) {
4783 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4784 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004785 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004787 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004788 }
Romain Guy06882f82009-06-10 13:36:04 -07004789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 public int getSwitchStateForDevice(int devid, int sw) {
4791 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4792 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004793 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004795 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 }
Romain Guy06882f82009-06-10 13:36:04 -07004797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004798 public int getScancodeState(int sw) {
4799 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4800 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004801 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004803 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004804 }
Romain Guy06882f82009-06-10 13:36:04 -07004805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 public int getScancodeStateForDevice(int devid, int sw) {
4807 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4808 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004809 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004810 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004811 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004812 }
Romain Guy06882f82009-06-10 13:36:04 -07004813
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004814 public int getTrackballScancodeState(int sw) {
4815 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4816 "getTrackballScancodeState()")) {
4817 throw new SecurityException("Requires READ_INPUT_STATE permission");
4818 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004819 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004820 }
4821
4822 public int getDPadScancodeState(int sw) {
4823 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4824 "getDPadScancodeState()")) {
4825 throw new SecurityException("Requires READ_INPUT_STATE permission");
4826 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004827 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004828 }
4829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 public int getKeycodeState(int sw) {
4831 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4832 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004833 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004835 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 }
Romain Guy06882f82009-06-10 13:36:04 -07004837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 public int getKeycodeStateForDevice(int devid, int sw) {
4839 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4840 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004841 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004843 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 }
Romain Guy06882f82009-06-10 13:36:04 -07004845
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004846 public int getTrackballKeycodeState(int sw) {
4847 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4848 "getTrackballKeycodeState()")) {
4849 throw new SecurityException("Requires READ_INPUT_STATE permission");
4850 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004851 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004852 }
4853
4854 public int getDPadKeycodeState(int sw) {
4855 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4856 "getDPadKeycodeState()")) {
4857 throw new SecurityException("Requires READ_INPUT_STATE permission");
4858 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004859 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004860 }
Jeff Browna41ca772010-08-11 14:46:32 -07004861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004863 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 }
Romain Guy06882f82009-06-10 13:36:04 -07004865
Jeff Browna41ca772010-08-11 14:46:32 -07004866 public InputChannel monitorInput(String inputChannelName) {
4867 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4868 "monitorInput()")) {
4869 throw new SecurityException("Requires READ_INPUT_STATE permission");
4870 }
4871 return mInputManager.monitorInput(inputChannelName);
4872 }
4873
Jeff Brown8d608662010-08-30 03:02:23 -07004874 public InputDevice getInputDevice(int deviceId) {
4875 return mInputManager.getInputDevice(deviceId);
4876 }
4877
4878 public int[] getInputDeviceIds() {
4879 return mInputManager.getInputDeviceIds();
4880 }
4881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 public void enableScreenAfterBoot() {
4883 synchronized(mWindowMap) {
4884 if (mSystemBooted) {
4885 return;
4886 }
4887 mSystemBooted = true;
4888 }
Romain Guy06882f82009-06-10 13:36:04 -07004889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 performEnableScreen();
4891 }
Romain Guy06882f82009-06-10 13:36:04 -07004892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 public void enableScreenIfNeededLocked() {
4894 if (mDisplayEnabled) {
4895 return;
4896 }
4897 if (!mSystemBooted) {
4898 return;
4899 }
4900 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4901 }
Romain Guy06882f82009-06-10 13:36:04 -07004902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 public void performEnableScreen() {
4904 synchronized(mWindowMap) {
4905 if (mDisplayEnabled) {
4906 return;
4907 }
4908 if (!mSystemBooted) {
4909 return;
4910 }
Romain Guy06882f82009-06-10 13:36:04 -07004911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 // Don't enable the screen until all existing windows
4913 // have been drawn.
4914 final int N = mWindows.size();
4915 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004916 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004917 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004918 return;
4919 }
4920 }
Romain Guy06882f82009-06-10 13:36:04 -07004921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 mDisplayEnabled = true;
4923 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004924 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 StringWriter sw = new StringWriter();
4926 PrintWriter pw = new PrintWriter(sw);
4927 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004928 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 }
4930 try {
4931 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4932 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004933 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 Parcel data = Parcel.obtain();
4935 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4936 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4937 data, null, 0);
4938 data.recycle();
4939 }
4940 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004941 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942 }
4943 }
Romain Guy06882f82009-06-10 13:36:04 -07004944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004947 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004948 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4949 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950 }
Romain Guy06882f82009-06-10 13:36:04 -07004951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 public void setInTouchMode(boolean mode) {
4953 synchronized(mWindowMap) {
4954 mInTouchMode = mode;
4955 }
4956 }
4957
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004958 // TODO: more accounting of which pid(s) turned it on, keep count,
4959 // only allow disables from pids which have count on, etc.
4960 public void showStrictModeViolation(boolean on) {
4961 int pid = Binder.getCallingPid();
4962 synchronized(mWindowMap) {
4963 // Ignoring requests to enable the red border from clients
4964 // which aren't on screen. (e.g. Broadcast Receivers in
4965 // the background..)
4966 if (on) {
4967 boolean isVisible = false;
4968 for (WindowState ws : mWindows) {
4969 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4970 isVisible = true;
4971 break;
4972 }
4973 }
4974 if (!isVisible) {
4975 return;
4976 }
4977 }
4978
4979 Surface.openTransaction();
4980 if (mStrictModeFlash == null) {
4981 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4982 }
4983 mStrictModeFlash.setVisibility(on);
4984 Surface.closeTransaction();
4985 }
4986 }
4987
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004988 public void setStrictModeVisualIndicatorPreference(String value) {
4989 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4990 }
4991
Dianne Hackbornd2835932010-12-13 16:28:46 -08004992 public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004993 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4994 "screenshotApplications()")) {
4995 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4996 }
4997
4998 Bitmap rawss;
4999
Dianne Hackbornd2835932010-12-13 16:28:46 -08005000 int maxLayer = 0;
5001 boolean foundApp;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005002 final Rect frame = new Rect();
5003
5004 float scale;
5005 int sw, sh, dw, dh;
5006 int rot;
5007
5008 synchronized(mWindowMap) {
5009 long ident = Binder.clearCallingIdentity();
5010
5011 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
5012 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
5013 + TYPE_LAYER_OFFSET;
5014 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5015
5016 // Figure out the part of the screen that is actually the app.
5017 for (int i=0; i<mWindows.size(); i++) {
5018 WindowState ws = mWindows.get(i);
5019 if (ws.mSurface == null) {
5020 continue;
5021 }
5022 if (ws.mLayer >= aboveAppLayer) {
5023 break;
5024 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005025 if (appToken != null && (ws.mAppToken == null
5026 || ws.mAppToken.token != appToken)) {
5027 continue;
5028 }
5029 if (maxLayer < ws.mAnimLayer) {
5030 maxLayer = ws.mAnimLayer;
5031 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005032 final Rect wf = ws.mFrame;
5033 final Rect cr = ws.mContentInsets;
5034 int left = wf.left + cr.left;
5035 int top = wf.top + cr.top;
5036 int right = wf.right - cr.right;
5037 int bottom = wf.bottom - cr.bottom;
5038 frame.union(left, top, right, bottom);
5039 }
5040 Binder.restoreCallingIdentity(ident);
5041
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005042 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005043 return null;
5044 }
5045
5046 // The screenshot API does not apply the current screen rotation.
5047 rot = mDisplay.getRotation();
5048 int fw = frame.width();
5049 int fh = frame.height();
5050
5051 // First try reducing to fit in x dimension.
5052 scale = maxWidth/(float)fw;
5053 sw = maxWidth;
5054 sh = (int)(fh*scale);
5055 if (sh > maxHeight) {
5056 // y dimension became too long; constrain by that.
5057 scale = maxHeight/(float)fh;
5058 sw = (int)(fw*scale);
5059 sh = maxHeight;
5060 }
5061
5062 // The screen shot will contain the entire screen.
5063 dw = (int)(mDisplay.getWidth()*scale);
5064 dh = (int)(mDisplay.getHeight()*scale);
5065 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5066 int tmp = dw;
5067 dw = dh;
5068 dh = tmp;
5069 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5070 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005071 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005072 }
5073
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005074 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005075 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
5076 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005077 return null;
5078 }
5079
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005080 Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
5081 Matrix matrix = new Matrix();
5082 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5083 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
5084 Canvas canvas = new Canvas(bm);
5085 canvas.drawBitmap(rawss, matrix, null);
5086
5087 rawss.recycle();
5088 return bm;
5089 }
5090
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005091 public void freezeRotation() {
5092 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5093 "setRotation()")) {
5094 throw new SecurityException("Requires SET_ORIENTATION permission");
5095 }
5096
5097 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
5098 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5099 }
5100
5101 public void thawRotation() {
5102 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5103 "setRotation()")) {
5104 throw new SecurityException("Requires SET_ORIENTATION permission");
5105 }
5106
5107 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
5108 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5109 }
5110
Romain Guy06882f82009-06-10 13:36:04 -07005111 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005112 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005114 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005115 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005116 }
5117
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005118 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 }
Romain Guy06882f82009-06-10 13:36:04 -07005120
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005121 public void setRotationUnchecked(int rotation,
5122 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005123 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07005125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 long origId = Binder.clearCallingIdentity();
5127 boolean changed;
5128 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005129 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005130 }
Romain Guy06882f82009-06-10 13:36:04 -07005131
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005132 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 sendNewConfiguration();
5134 }
Romain Guy06882f82009-06-10 13:36:04 -07005135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005136 Binder.restoreCallingIdentity(origId);
5137 }
Romain Guy06882f82009-06-10 13:36:04 -07005138
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005139 /**
5140 * Apply a new rotation to the screen, respecting the requests of
5141 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
5142 * re-evaluate the desired rotation.
5143 *
5144 * Returns null if the rotation has been changed. In this case YOU
5145 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
5146 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005147 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
Christopher Tateccd24de2011-01-12 15:02:55 -08005148 if (mDragState != null) {
5149 // Potential rotation during a drag. Don't do the rotation now, but make
5150 // a note to perform the rotation later.
5151 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation during drag");
5152 mDragState.setDeferredRotation(rotation, animFlags);
5153 return false;
5154 }
5155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 boolean changed;
5157 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
5158 rotation = mRequestedRotation;
5159 } else {
5160 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07005161 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005163 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07005164 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005166 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07005168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005170 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 "Rotation changed to " + rotation
5172 + " from " + mRotation
5173 + " (forceApp=" + mForcedAppOrientation
5174 + ", req=" + mRequestedRotation + ")");
5175 mRotation = rotation;
5176 mWindowsFreezingScreen = true;
5177 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5178 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
5179 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005180 mWaitingForConfig = true;
5181 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005183 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005184 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 if (mDisplayEnabled) {
Dianne Hackborna1111872010-11-23 20:55:11 -08005186 if (CUSTOM_SCREEN_ROTATION) {
5187 Surface.freezeDisplay(0);
5188 Surface.openTransaction();
5189 if (mScreenRotationAnimation != null) {
5190 mScreenRotationAnimation.setRotation(rotation);
5191 }
5192 Surface.closeTransaction();
5193 Surface.setOrientation(0, rotation, animFlags);
5194 Surface.unfreezeDisplay(0);
5195 } else {
5196 Surface.setOrientation(0, rotation, animFlags);
5197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 }
5199 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005200 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 if (w.mSurface != null) {
5202 w.mOrientationChanging = true;
5203 }
5204 }
5205 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5206 try {
5207 mRotationWatchers.get(i).onRotationChanged(rotation);
5208 } catch (RemoteException e) {
5209 }
5210 }
5211 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 return changed;
5214 }
Romain Guy06882f82009-06-10 13:36:04 -07005215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005216 public int getRotation() {
5217 return mRotation;
5218 }
5219
5220 public int watchRotation(IRotationWatcher watcher) {
5221 final IBinder watcherBinder = watcher.asBinder();
5222 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5223 public void binderDied() {
5224 synchronized (mWindowMap) {
5225 for (int i=0; i<mRotationWatchers.size(); i++) {
5226 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005227 IRotationWatcher removed = mRotationWatchers.remove(i);
5228 if (removed != null) {
5229 removed.asBinder().unlinkToDeath(this, 0);
5230 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005231 i--;
5232 }
5233 }
5234 }
5235 }
5236 };
Romain Guy06882f82009-06-10 13:36:04 -07005237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005238 synchronized (mWindowMap) {
5239 try {
5240 watcher.asBinder().linkToDeath(dr, 0);
5241 mRotationWatchers.add(watcher);
5242 } catch (RemoteException e) {
5243 // Client died, no cleanup needed.
5244 }
Romain Guy06882f82009-06-10 13:36:04 -07005245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005246 return mRotation;
5247 }
5248 }
5249
5250 /**
5251 * Starts the view server on the specified port.
5252 *
5253 * @param port The port to listener to.
5254 *
5255 * @return True if the server was successfully started, false otherwise.
5256 *
5257 * @see com.android.server.ViewServer
5258 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5259 */
5260 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005261 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 return false;
5263 }
5264
5265 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5266 return false;
5267 }
5268
5269 if (port < 1024) {
5270 return false;
5271 }
5272
5273 if (mViewServer != null) {
5274 if (!mViewServer.isRunning()) {
5275 try {
5276 return mViewServer.start();
5277 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005278 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 }
5280 }
5281 return false;
5282 }
5283
5284 try {
5285 mViewServer = new ViewServer(this, port);
5286 return mViewServer.start();
5287 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005288 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005289 }
5290 return false;
5291 }
5292
Romain Guy06882f82009-06-10 13:36:04 -07005293 private boolean isSystemSecure() {
5294 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5295 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5296 }
5297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 /**
5299 * Stops the view server if it exists.
5300 *
5301 * @return True if the server stopped, false if it wasn't started or
5302 * couldn't be stopped.
5303 *
5304 * @see com.android.server.ViewServer
5305 */
5306 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005307 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308 return false;
5309 }
5310
5311 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5312 return false;
5313 }
5314
5315 if (mViewServer != null) {
5316 return mViewServer.stop();
5317 }
5318 return false;
5319 }
5320
5321 /**
5322 * Indicates whether the view server is running.
5323 *
5324 * @return True if the server is running, false otherwise.
5325 *
5326 * @see com.android.server.ViewServer
5327 */
5328 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005329 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 return false;
5331 }
5332
5333 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5334 return false;
5335 }
5336
5337 return mViewServer != null && mViewServer.isRunning();
5338 }
5339
5340 /**
5341 * Lists all availble windows in the system. The listing is written in the
5342 * specified Socket's output stream with the following syntax:
5343 * windowHashCodeInHexadecimal windowName
5344 * Each line of the ouput represents a different window.
5345 *
5346 * @param client The remote client to send the listing to.
5347 * @return False if an error occured, true otherwise.
5348 */
5349 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005350 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 return false;
5352 }
5353
5354 boolean result = true;
5355
Jeff Browne33348b2010-07-15 23:54:05 -07005356 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005358 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005359 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005360 }
5361
5362 BufferedWriter out = null;
5363
5364 // Any uncaught exception will crash the system process
5365 try {
5366 OutputStream clientStream = client.getOutputStream();
5367 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5368
5369 final int count = windows.length;
5370 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005371 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 out.write(Integer.toHexString(System.identityHashCode(w)));
5373 out.write(' ');
5374 out.append(w.mAttrs.getTitle());
5375 out.write('\n');
5376 }
5377
5378 out.write("DONE.\n");
5379 out.flush();
5380 } catch (Exception e) {
5381 result = false;
5382 } finally {
5383 if (out != null) {
5384 try {
5385 out.close();
5386 } catch (IOException e) {
5387 result = false;
5388 }
5389 }
5390 }
5391
5392 return result;
5393 }
5394
5395 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005396 * Returns the focused window in the following format:
5397 * windowHashCodeInHexadecimal windowName
5398 *
5399 * @param client The remote client to send the listing to.
5400 * @return False if an error occurred, true otherwise.
5401 */
5402 boolean viewServerGetFocusedWindow(Socket client) {
5403 if (isSystemSecure()) {
5404 return false;
5405 }
5406
5407 boolean result = true;
5408
5409 WindowState focusedWindow = getFocusedWindow();
5410
5411 BufferedWriter out = null;
5412
5413 // Any uncaught exception will crash the system process
5414 try {
5415 OutputStream clientStream = client.getOutputStream();
5416 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5417
5418 if(focusedWindow != null) {
5419 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5420 out.write(' ');
5421 out.append(focusedWindow.mAttrs.getTitle());
5422 }
5423 out.write('\n');
5424 out.flush();
5425 } catch (Exception e) {
5426 result = false;
5427 } finally {
5428 if (out != null) {
5429 try {
5430 out.close();
5431 } catch (IOException e) {
5432 result = false;
5433 }
5434 }
5435 }
5436
5437 return result;
5438 }
5439
5440 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 * Sends a command to a target window. The result of the command, if any, will be
5442 * written in the output stream of the specified socket.
5443 *
5444 * The parameters must follow this syntax:
5445 * windowHashcode extra
5446 *
5447 * Where XX is the length in characeters of the windowTitle.
5448 *
5449 * The first parameter is the target window. The window with the specified hashcode
5450 * will be the target. If no target can be found, nothing happens. The extra parameters
5451 * will be delivered to the target window and as parameters to the command itself.
5452 *
5453 * @param client The remote client to sent the result, if any, to.
5454 * @param command The command to execute.
5455 * @param parameters The command parameters.
5456 *
5457 * @return True if the command was successfully delivered, false otherwise. This does
5458 * not indicate whether the command itself was successful.
5459 */
5460 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005461 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 return false;
5463 }
5464
5465 boolean success = true;
5466 Parcel data = null;
5467 Parcel reply = null;
5468
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005469 BufferedWriter out = null;
5470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005471 // Any uncaught exception will crash the system process
5472 try {
5473 // Find the hashcode of the window
5474 int index = parameters.indexOf(' ');
5475 if (index == -1) {
5476 index = parameters.length();
5477 }
5478 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005479 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005480
5481 // Extract the command's parameter after the window description
5482 if (index < parameters.length()) {
5483 parameters = parameters.substring(index + 1);
5484 } else {
5485 parameters = "";
5486 }
5487
5488 final WindowManagerService.WindowState window = findWindow(hashCode);
5489 if (window == null) {
5490 return false;
5491 }
5492
5493 data = Parcel.obtain();
5494 data.writeInterfaceToken("android.view.IWindow");
5495 data.writeString(command);
5496 data.writeString(parameters);
5497 data.writeInt(1);
5498 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5499
5500 reply = Parcel.obtain();
5501
5502 final IBinder binder = window.mClient.asBinder();
5503 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5504 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5505
5506 reply.readException();
5507
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005508 if (!client.isOutputShutdown()) {
5509 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5510 out.write("DONE\n");
5511 out.flush();
5512 }
5513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005515 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 success = false;
5517 } finally {
5518 if (data != null) {
5519 data.recycle();
5520 }
5521 if (reply != null) {
5522 reply.recycle();
5523 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005524 if (out != null) {
5525 try {
5526 out.close();
5527 } catch (IOException e) {
5528
5529 }
5530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 }
5532
5533 return success;
5534 }
5535
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005536 public void addWindowChangeListener(WindowChangeListener listener) {
5537 synchronized(mWindowMap) {
5538 mWindowChangeListeners.add(listener);
5539 }
5540 }
5541
5542 public void removeWindowChangeListener(WindowChangeListener listener) {
5543 synchronized(mWindowMap) {
5544 mWindowChangeListeners.remove(listener);
5545 }
5546 }
5547
5548 private void notifyWindowsChanged() {
5549 WindowChangeListener[] windowChangeListeners;
5550 synchronized(mWindowMap) {
5551 if(mWindowChangeListeners.isEmpty()) {
5552 return;
5553 }
5554 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5555 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5556 }
5557 int N = windowChangeListeners.length;
5558 for(int i = 0; i < N; i++) {
5559 windowChangeListeners[i].windowsChanged();
5560 }
5561 }
5562
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005563 private void notifyFocusChanged() {
5564 WindowChangeListener[] windowChangeListeners;
5565 synchronized(mWindowMap) {
5566 if(mWindowChangeListeners.isEmpty()) {
5567 return;
5568 }
5569 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5570 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5571 }
5572 int N = windowChangeListeners.length;
5573 for(int i = 0; i < N; i++) {
5574 windowChangeListeners[i].focusChanged();
5575 }
5576 }
5577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 private WindowState findWindow(int hashCode) {
5579 if (hashCode == -1) {
5580 return getFocusedWindow();
5581 }
5582
5583 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005584 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 final int count = windows.size();
5586
5587 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005588 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005589 if (System.identityHashCode(w) == hashCode) {
5590 return w;
5591 }
5592 }
5593 }
5594
5595 return null;
5596 }
5597
5598 /*
5599 * Instruct the Activity Manager to fetch the current configuration and broadcast
5600 * that to config-changed listeners if appropriate.
5601 */
5602 void sendNewConfiguration() {
5603 try {
5604 mActivityManager.updateConfiguration(null);
5605 } catch (RemoteException e) {
5606 }
5607 }
Romain Guy06882f82009-06-10 13:36:04 -07005608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 public Configuration computeNewConfiguration() {
5610 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005611 return computeNewConfigurationLocked();
5612 }
5613 }
Romain Guy06882f82009-06-10 13:36:04 -07005614
Dianne Hackbornc485a602009-03-24 22:39:49 -07005615 Configuration computeNewConfigurationLocked() {
5616 Configuration config = new Configuration();
5617 if (!computeNewConfigurationLocked(config)) {
5618 return null;
5619 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005620 return config;
5621 }
Romain Guy06882f82009-06-10 13:36:04 -07005622
Dianne Hackbornc485a602009-03-24 22:39:49 -07005623 boolean computeNewConfigurationLocked(Configuration config) {
5624 if (mDisplay == null) {
5625 return false;
5626 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005627
5628 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005629
5630 // Use the effective "visual" dimensions based on current rotation
5631 final boolean rotated = (mRotation == Surface.ROTATION_90
5632 || mRotation == Surface.ROTATION_270);
5633 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5634 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5635
Dianne Hackbornc485a602009-03-24 22:39:49 -07005636 int orientation = Configuration.ORIENTATION_SQUARE;
5637 if (dw < dh) {
5638 orientation = Configuration.ORIENTATION_PORTRAIT;
5639 } else if (dw > dh) {
5640 orientation = Configuration.ORIENTATION_LANDSCAPE;
5641 }
5642 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005643
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005644 DisplayMetrics dm = new DisplayMetrics();
5645 mDisplay.getMetrics(dm);
5646 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5647
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005648 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005649 // Note we only do this once because at this point we don't
5650 // expect the screen to change in this way at runtime, and want
5651 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005652 int longSize = dw;
5653 int shortSize = dh;
5654 if (longSize < shortSize) {
5655 int tmp = longSize;
5656 longSize = shortSize;
5657 shortSize = tmp;
5658 }
5659 longSize = (int)(longSize/dm.density);
5660 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005661
Dianne Hackborn723738c2009-06-25 19:48:04 -07005662 // These semi-magic numbers define our compatibility modes for
5663 // applications with different screens. Don't change unless you
5664 // make sure to test lots and lots of apps!
5665 if (longSize < 470) {
5666 // This is shorter than an HVGA normal density screen (which
5667 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005668 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5669 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005670 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005671 // What size is this screen screen?
5672 if (longSize >= 800 && shortSize >= 600) {
5673 // SVGA or larger screens at medium density are the point
5674 // at which we consider it to be an extra large screen.
5675 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005676 } else if (longSize >= 530 && shortSize >= 400) {
5677 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005678 // at which we consider it to be a large screen.
5679 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5680 } else {
5681 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005682
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005683 // If this screen is wider than normal HVGA, or taller
5684 // than FWVGA, then for old apps we want to run in size
5685 // compatibility mode.
5686 if (shortSize > 321 || longSize > 570) {
5687 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5688 }
5689 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005690
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005691 // Is this a long screen?
5692 if (((longSize*3)/5) >= (shortSize-1)) {
5693 // Anything wider than WVGA (5:3) is considering to be long.
5694 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5695 } else {
5696 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5697 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005698 }
5699 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005700 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005701
Dianne Hackbornc485a602009-03-24 22:39:49 -07005702 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5703 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5704 mPolicy.adjustConfigurationLw(config);
5705 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005707
5708 // -------------------------------------------------------------
5709 // Drag and drop
5710 // -------------------------------------------------------------
5711
5712 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005713 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005714 if (DEBUG_DRAG) {
5715 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005716 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005717 + " asbinder=" + window.asBinder());
5718 }
5719
5720 final int callerPid = Binder.getCallingPid();
5721 final long origId = Binder.clearCallingIdentity();
5722 IBinder token = null;
5723
5724 try {
5725 synchronized (mWindowMap) {
5726 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005727 if (mDragState == null) {
5728 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5729 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5730 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005731 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005732 token = new Binder();
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005733 // TODO: preserve flags param in DragState
5734 mDragState = new DragState(token, surface, 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005735 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005736 token = mDragState.mToken = new Binder();
5737
5738 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005739 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5740 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005741 mH.sendMessageDelayed(msg, 5000);
5742 } else {
5743 Slog.w(TAG, "Drag already in progress");
5744 }
5745 } catch (Surface.OutOfResourcesException e) {
5746 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5747 if (mDragState != null) {
5748 mDragState.reset();
5749 mDragState = null;
5750 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005751 }
5752 }
5753 } finally {
5754 Binder.restoreCallingIdentity(origId);
5755 }
5756
5757 return token;
5758 }
5759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 // -------------------------------------------------------------
5761 // Input Events and Focus Management
5762 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005763
Jeff Brown349703e2010-06-22 01:27:15 -07005764 InputMonitor mInputMonitor = new InputMonitor();
5765
5766 /* Tracks the progress of input dispatch and ensures that input dispatch state
5767 * is kept in sync with changes in window focus, visibility, registration, and
5768 * other relevant Window Manager state transitions. */
5769 final class InputMonitor {
5770 // Current window with input focus for keys and other non-touch events. May be null.
5771 private WindowState mInputFocus;
5772
5773 // When true, prevents input dispatch from proceeding until set to false again.
5774 private boolean mInputDispatchFrozen;
5775
5776 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5777 private boolean mInputDispatchEnabled = true;
5778
5779 // Temporary list of windows information to provide to the input dispatcher.
5780 private InputWindowList mTempInputWindows = new InputWindowList();
5781
5782 // Temporary input application object to provide to the input dispatcher.
5783 private InputApplication mTempInputApplication = new InputApplication();
5784
5785 /* Notifies the window manager about a broken input channel.
5786 *
5787 * Called by the InputManager.
5788 */
Jeff Brown928e0542011-01-10 11:17:36 -08005789 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
5790 if (inputWindowHandle == null) {
5791 return;
5792 }
5793
Jeff Brown349703e2010-06-22 01:27:15 -07005794 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005795 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown349703e2010-06-22 01:27:15 -07005796 Slog.i(TAG, "WINDOW DIED " + windowState);
5797 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005798 }
5799 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005800
Jeff Brown519e0242010-09-15 15:18:56 -07005801 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005802 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005803 *
5804 * Called by the InputManager.
5805 */
Jeff Brown928e0542011-01-10 11:17:36 -08005806 public long notifyANR(InputApplicationHandle inputApplicationHandle,
5807 InputWindowHandle inputWindowHandle) {
Jeff Brown519e0242010-09-15 15:18:56 -07005808 AppWindowToken appWindowToken = null;
Jeff Brown928e0542011-01-10 11:17:36 -08005809 if (inputWindowHandle != null) {
Jeff Brown519e0242010-09-15 15:18:56 -07005810 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005811 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown519e0242010-09-15 15:18:56 -07005812 if (windowState != null) {
5813 Slog.i(TAG, "Input event dispatching timed out sending to "
5814 + windowState.mAttrs.getTitle());
5815 appWindowToken = windowState.mAppToken;
5816 }
Jeff Brown349703e2010-06-22 01:27:15 -07005817 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005818 }
5819
Jeff Brown928e0542011-01-10 11:17:36 -08005820 if (appWindowToken == null && inputApplicationHandle != null) {
5821 appWindowToken = inputApplicationHandle.appWindowToken;
Jeff Brown519e0242010-09-15 15:18:56 -07005822 Slog.i(TAG, "Input event dispatching timed out sending to application "
5823 + appWindowToken.stringName);
5824 }
Jeff Brown349703e2010-06-22 01:27:15 -07005825
Jeff Brown519e0242010-09-15 15:18:56 -07005826 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005827 try {
5828 // Notify the activity manager about the timeout and let it decide whether
5829 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005830 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005831 if (! abort) {
5832 // The activity manager declined to abort dispatching.
5833 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005834 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005835 }
Jeff Brown349703e2010-06-22 01:27:15 -07005836 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005837 }
5838 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005839 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005840 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005841
Chris Tatea32dcf72010-10-14 12:13:50 -07005842 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005843 final InputWindow inputWindow = windowList.add();
5844 inputWindow.inputChannel = mDragState.mServerChannel;
5845 inputWindow.name = "drag";
5846 inputWindow.layoutParamsFlags = 0;
5847 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5848 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5849 inputWindow.visible = true;
5850 inputWindow.canReceiveKeys = false;
5851 inputWindow.hasFocus = true;
5852 inputWindow.hasWallpaper = false;
5853 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07005854 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07005855 inputWindow.ownerPid = Process.myPid();
5856 inputWindow.ownerUid = Process.myUid();
5857
5858 // The drag window covers the entire display
5859 inputWindow.frameLeft = 0;
5860 inputWindow.frameTop = 0;
5861 inputWindow.frameRight = mDisplay.getWidth();
5862 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005863
Christopher Tatea53146c2010-09-07 11:57:52 -07005864 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5865 inputWindow.visibleFrameTop = inputWindow.frameTop;
5866 inputWindow.visibleFrameRight = inputWindow.frameRight;
5867 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5868
5869 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5870 inputWindow.touchableAreaTop = inputWindow.frameTop;
5871 inputWindow.touchableAreaRight = inputWindow.frameRight;
5872 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5873 }
5874
Jeff Brown349703e2010-06-22 01:27:15 -07005875 /* Updates the cached window information provided to the input dispatcher. */
5876 public void updateInputWindowsLw() {
5877 // Populate the input window list with information about all of the windows that
5878 // could potentially receive input.
5879 // As an optimization, we could try to prune the list of windows but this turns
5880 // out to be difficult because only the native code knows for sure which window
5881 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005882 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005883
5884 // If there's a drag in flight, provide a pseudowindow to catch drag input
5885 final boolean inDrag = (mDragState != null);
5886 if (inDrag) {
5887 if (DEBUG_DRAG) {
5888 Log.d(TAG, "Inserting drag window");
5889 }
Chris Tatea32dcf72010-10-14 12:13:50 -07005890 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07005891 }
5892
Jeff Brown7fbdc842010-06-17 20:52:56 -07005893 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005894 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005895 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005896 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005897 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005898 continue;
5899 }
5900
Jeff Brown349703e2010-06-22 01:27:15 -07005901 final int flags = child.mAttrs.flags;
5902 final int type = child.mAttrs.type;
5903
5904 final boolean hasFocus = (child == mInputFocus);
5905 final boolean isVisible = child.isVisibleLw();
5906 final boolean hasWallpaper = (child == mWallpaperTarget)
5907 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005908
5909 // If there's a drag in progress and 'child' is a potential drop target,
5910 // make sure it's been told about the drag
5911 if (inDrag && isVisible) {
5912 mDragState.sendDragStartedIfNeededLw(child);
5913 }
5914
Jeff Brown349703e2010-06-22 01:27:15 -07005915 // Add a window to our list of input windows.
5916 final InputWindow inputWindow = mTempInputWindows.add();
Jeff Brown928e0542011-01-10 11:17:36 -08005917 inputWindow.inputWindowHandle = child.mInputWindowHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07005918 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005919 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005920 inputWindow.layoutParamsFlags = flags;
5921 inputWindow.layoutParamsType = type;
5922 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5923 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005924 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005925 inputWindow.hasFocus = hasFocus;
5926 inputWindow.hasWallpaper = hasWallpaper;
5927 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005928 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005929 inputWindow.ownerPid = child.mSession.mPid;
5930 inputWindow.ownerUid = child.mSession.mUid;
5931
5932 final Rect frame = child.mFrame;
5933 inputWindow.frameLeft = frame.left;
5934 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005935 inputWindow.frameRight = frame.right;
5936 inputWindow.frameBottom = frame.bottom;
5937
5938 final Rect visibleFrame = child.mVisibleFrame;
5939 inputWindow.visibleFrameLeft = visibleFrame.left;
5940 inputWindow.visibleFrameTop = visibleFrame.top;
5941 inputWindow.visibleFrameRight = visibleFrame.right;
5942 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005943
5944 switch (child.mTouchableInsets) {
5945 default:
5946 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5947 inputWindow.touchableAreaLeft = frame.left;
5948 inputWindow.touchableAreaTop = frame.top;
5949 inputWindow.touchableAreaRight = frame.right;
5950 inputWindow.touchableAreaBottom = frame.bottom;
5951 break;
5952
5953 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5954 Rect inset = child.mGivenContentInsets;
5955 inputWindow.touchableAreaLeft = frame.left + inset.left;
5956 inputWindow.touchableAreaTop = frame.top + inset.top;
5957 inputWindow.touchableAreaRight = frame.right - inset.right;
5958 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5959 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005960 }
Jeff Brown349703e2010-06-22 01:27:15 -07005961
5962 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5963 Rect inset = child.mGivenVisibleInsets;
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;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005968 break;
5969 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005970 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005971 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005972
Jeff Brown349703e2010-06-22 01:27:15 -07005973 // Send windows to native code.
5974 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005975
Jeff Brown349703e2010-06-22 01:27:15 -07005976 // Clear the list in preparation for the next round.
5977 // Also avoids keeping InputChannel objects referenced unnecessarily.
5978 mTempInputWindows.clear();
5979 }
5980
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005981 /* Notifies that the lid switch changed state. */
5982 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5983 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5984 }
5985
Jeff Brown349703e2010-06-22 01:27:15 -07005986 /* Provides an opportunity for the window manager policy to intercept early key
5987 * processing as soon as the key has been read from the device. */
Jeff Brown1f245102010-11-18 20:53:46 -08005988 public int interceptKeyBeforeQueueing(
5989 KeyEvent event, int policyFlags, boolean isScreenOn) {
5990 return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005991 }
5992
5993 /* Provides an opportunity for the window manager policy to process a key before
5994 * ordinary dispatch. */
Jeff Brown1f245102010-11-18 20:53:46 -08005995 public boolean interceptKeyBeforeDispatching(
Jeff Brown928e0542011-01-10 11:17:36 -08005996 InputWindowHandle focus, KeyEvent event, int policyFlags) {
5997 WindowState windowState = (WindowState) focus.windowState;
Jeff Brown1f245102010-11-18 20:53:46 -08005998 return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005999 }
6000
Jeff Brown3915bb82010-11-05 15:02:16 -07006001 /* Provides an opportunity for the window manager policy to process a key that
6002 * the application did not handle. */
Jeff Brown49ed71d2010-12-06 17:13:33 -08006003 public KeyEvent dispatchUnhandledKey(
Jeff Brown928e0542011-01-10 11:17:36 -08006004 InputWindowHandle focus, KeyEvent event, int policyFlags) {
6005 WindowState windowState = (WindowState) focus.windowState;
Jeff Brown1f245102010-11-18 20:53:46 -08006006 return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07006007 }
6008
Jeff Brown349703e2010-06-22 01:27:15 -07006009 /* Called when the current input focus changes.
6010 * Layer assignment is assumed to be complete by the time this is called.
6011 */
6012 public void setInputFocusLw(WindowState newWindow) {
6013 if (DEBUG_INPUT) {
6014 Slog.d(TAG, "Input focus has changed to " + newWindow);
6015 }
6016
6017 if (newWindow != mInputFocus) {
6018 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07006019 // Displaying a window implicitly causes dispatching to be unpaused.
6020 // This is to protect against bugs if someone pauses dispatching but
6021 // forgets to resume.
6022 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006023 }
Jeff Brown349703e2010-06-22 01:27:15 -07006024
6025 mInputFocus = newWindow;
6026 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006027 }
6028 }
6029
Jeff Brown349703e2010-06-22 01:27:15 -07006030 public void setFocusedAppLw(AppWindowToken newApp) {
6031 // Focused app has changed.
6032 if (newApp == null) {
6033 mInputManager.setFocusedApplication(null);
6034 } else {
Jeff Brown928e0542011-01-10 11:17:36 -08006035 mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07006036 mTempInputApplication.name = newApp.toString();
6037 mTempInputApplication.dispatchingTimeoutNanos =
6038 newApp.inputDispatchingTimeoutNanos;
Jeff Brown928e0542011-01-10 11:17:36 -08006039
Jeff Brown349703e2010-06-22 01:27:15 -07006040 mInputManager.setFocusedApplication(mTempInputApplication);
Jeff Brown928e0542011-01-10 11:17:36 -08006041
6042 mTempInputApplication.recycle();
Jeff Brown349703e2010-06-22 01:27:15 -07006043 }
6044 }
6045
Jeff Brown349703e2010-06-22 01:27:15 -07006046 public void pauseDispatchingLw(WindowToken window) {
6047 if (! window.paused) {
6048 if (DEBUG_INPUT) {
6049 Slog.v(TAG, "Pausing WindowToken " + window);
6050 }
6051
6052 window.paused = true;
6053 updateInputWindowsLw();
6054 }
6055 }
6056
6057 public void resumeDispatchingLw(WindowToken window) {
6058 if (window.paused) {
6059 if (DEBUG_INPUT) {
6060 Slog.v(TAG, "Resuming WindowToken " + window);
6061 }
6062
6063 window.paused = false;
6064 updateInputWindowsLw();
6065 }
6066 }
6067
6068 public void freezeInputDispatchingLw() {
6069 if (! mInputDispatchFrozen) {
6070 if (DEBUG_INPUT) {
6071 Slog.v(TAG, "Freezing input dispatching");
6072 }
6073
6074 mInputDispatchFrozen = true;
6075 updateInputDispatchModeLw();
6076 }
6077 }
6078
6079 public void thawInputDispatchingLw() {
6080 if (mInputDispatchFrozen) {
6081 if (DEBUG_INPUT) {
6082 Slog.v(TAG, "Thawing input dispatching");
6083 }
6084
6085 mInputDispatchFrozen = false;
6086 updateInputDispatchModeLw();
6087 }
6088 }
6089
6090 public void setEventDispatchingLw(boolean enabled) {
6091 if (mInputDispatchEnabled != enabled) {
6092 if (DEBUG_INPUT) {
6093 Slog.v(TAG, "Setting event dispatching to " + enabled);
6094 }
6095
6096 mInputDispatchEnabled = enabled;
6097 updateInputDispatchModeLw();
6098 }
6099 }
6100
6101 private void updateInputDispatchModeLw() {
6102 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
6103 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 public void pauseKeyDispatching(IBinder _token) {
6107 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6108 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006109 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 }
6111
6112 synchronized (mWindowMap) {
6113 WindowToken token = mTokenMap.get(_token);
6114 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006115 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006116 }
6117 }
6118 }
6119
6120 public void resumeKeyDispatching(IBinder _token) {
6121 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6122 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006123 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 }
6125
6126 synchronized (mWindowMap) {
6127 WindowToken token = mTokenMap.get(_token);
6128 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006129 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 }
6131 }
6132 }
6133
6134 public void setEventDispatching(boolean enabled) {
6135 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6136 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006137 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006138 }
6139
6140 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006141 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 }
6143 }
Romain Guy06882f82009-06-10 13:36:04 -07006144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 /**
6146 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006147 * Even when sync is false, this method may block while waiting for current
6148 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006149 *
6150 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 * {@link SystemClock#uptimeMillis()} as the timebase.)
6152 * @param sync If true, wait for the event to be completed before returning to the caller.
6153 * @return Returns true if event was dispatched, false if it was dropped for any reason
6154 */
6155 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6156 long downTime = ev.getDownTime();
6157 long eventTime = ev.getEventTime();
6158
6159 int action = ev.getAction();
6160 int code = ev.getKeyCode();
6161 int repeatCount = ev.getRepeatCount();
6162 int metaState = ev.getMetaState();
6163 int deviceId = ev.getDeviceId();
6164 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006165 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00006166 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006167
6168 if (source == InputDevice.SOURCE_UNKNOWN) {
6169 source = InputDevice.SOURCE_KEYBOARD;
6170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171
6172 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6173 if (downTime == 0) downTime = eventTime;
6174
6175 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08006176 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006178 final int pid = Binder.getCallingPid();
6179 final int uid = Binder.getCallingUid();
6180 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006181
Jeff Brownbbda99d2010-07-28 15:48:59 -07006182 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6183 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6184 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6185 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006186
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006187 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006188 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006189 }
6190
6191 /**
6192 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006193 * Even when sync is false, this method may block while waiting for current
6194 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006195 *
6196 * @param ev A motion event describing the pointer (touch) action. (As noted in
6197 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006198 * {@link SystemClock#uptimeMillis()} as the timebase.)
6199 * @param sync If true, wait for the event to be completed before returning to the caller.
6200 * @return Returns true if event was dispatched, false if it was dropped for any reason
6201 */
6202 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006203 final int pid = Binder.getCallingPid();
6204 final int uid = Binder.getCallingUid();
6205 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006206
Jeff Brownc5ed5912010-07-14 18:48:53 -07006207 MotionEvent newEvent = MotionEvent.obtain(ev);
6208 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6209 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6210 }
6211
Jeff Brownbbda99d2010-07-28 15:48:59 -07006212 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6213 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6214 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6215 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006216
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006217 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006218 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006219 }
Romain Guy06882f82009-06-10 13:36:04 -07006220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 /**
6222 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006223 * Even when sync is false, this method may block while waiting for current
6224 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006225 *
6226 * @param ev A motion event describing the trackball action. (As noted in
6227 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006228 * {@link SystemClock#uptimeMillis()} as the timebase.)
6229 * @param sync If true, wait for the event to be completed before returning to the caller.
6230 * @return Returns true if event was dispatched, false if it was dropped for any reason
6231 */
6232 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006233 final int pid = Binder.getCallingPid();
6234 final int uid = Binder.getCallingUid();
6235 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006236
Jeff Brownc5ed5912010-07-14 18:48:53 -07006237 MotionEvent newEvent = MotionEvent.obtain(ev);
6238 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6239 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6240 }
6241
Jeff Brownbbda99d2010-07-28 15:48:59 -07006242 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6243 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6244 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6245 INJECTION_TIMEOUT_MILLIS);
6246
6247 Binder.restoreCallingIdentity(ident);
6248 return reportInjectionResult(result);
6249 }
6250
6251 /**
6252 * Inject an input event into the UI without waiting for dispatch to commence.
6253 * This variant is useful for fire-and-forget input event injection. It does not
6254 * block any longer than it takes to enqueue the input event.
6255 *
6256 * @param ev An input event. (Be sure to set the input source correctly.)
6257 * @return Returns true if event was dispatched, false if it was dropped for any reason
6258 */
6259 public boolean injectInputEventNoWait(InputEvent ev) {
6260 final int pid = Binder.getCallingPid();
6261 final int uid = Binder.getCallingUid();
6262 final long ident = Binder.clearCallingIdentity();
6263
6264 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6265 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6266 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006267
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006268 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006269 return reportInjectionResult(result);
6270 }
6271
6272 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006273 switch (result) {
6274 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6275 Slog.w(TAG, "Input event injection permission denied.");
6276 throw new SecurityException(
6277 "Injecting to another application requires INJECT_EVENTS permission");
6278 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006279 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006280 return true;
6281 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6282 Slog.w(TAG, "Input event injection timed out.");
6283 return false;
6284 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6285 default:
6286 Slog.w(TAG, "Input event injection failed.");
6287 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 }
Romain Guy06882f82009-06-10 13:36:04 -07006290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 private WindowState getFocusedWindow() {
6292 synchronized (mWindowMap) {
6293 return getFocusedWindowLocked();
6294 }
6295 }
6296
6297 private WindowState getFocusedWindowLocked() {
6298 return mCurrentFocus;
6299 }
Romain Guy06882f82009-06-10 13:36:04 -07006300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 public boolean detectSafeMode() {
6302 mSafeMode = mPolicy.detectSafeMode();
6303 return mSafeMode;
6304 }
Romain Guy06882f82009-06-10 13:36:04 -07006305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006307 synchronized(mWindowMap) {
6308 if (mDisplay != null) {
6309 throw new IllegalStateException("Display already initialized");
6310 }
6311 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6312 mDisplay = wm.getDefaultDisplay();
6313 mInitialDisplayWidth = mDisplay.getWidth();
6314 mInitialDisplayHeight = mDisplay.getHeight();
Dianne Hackborn4c7cc342010-12-16 16:37:39 -08006315 mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
6316 Display.unmapDisplaySize(mInitialDisplayHeight));
Dianne Hackborn5132b372010-07-29 12:51:35 -07006317 }
6318
6319 try {
6320 mActivityManager.updateConfiguration(null);
6321 } catch (RemoteException e) {
6322 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006323
6324 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006325 }
6326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 // -------------------------------------------------------------
6328 // Client Session State
6329 // -------------------------------------------------------------
6330
6331 private final class Session extends IWindowSession.Stub
6332 implements IBinder.DeathRecipient {
6333 final IInputMethodClient mClient;
6334 final IInputContext mInputContext;
6335 final int mUid;
6336 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006337 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 SurfaceSession mSurfaceSession;
6339 int mNumWindow = 0;
6340 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 public Session(IInputMethodClient client, IInputContext inputContext) {
6343 mClient = client;
6344 mInputContext = inputContext;
6345 mUid = Binder.getCallingUid();
6346 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006347 StringBuilder sb = new StringBuilder();
6348 sb.append("Session{");
6349 sb.append(Integer.toHexString(System.identityHashCode(this)));
6350 sb.append(" uid ");
6351 sb.append(mUid);
6352 sb.append("}");
6353 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 synchronized (mWindowMap) {
6356 if (mInputMethodManager == null && mHaveInputMethods) {
6357 IBinder b = ServiceManager.getService(
6358 Context.INPUT_METHOD_SERVICE);
6359 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6360 }
6361 }
6362 long ident = Binder.clearCallingIdentity();
6363 try {
6364 // Note: it is safe to call in to the input method manager
6365 // here because we are not holding our lock.
6366 if (mInputMethodManager != null) {
6367 mInputMethodManager.addClient(client, inputContext,
6368 mUid, mPid);
6369 } else {
6370 client.setUsingInputMethod(false);
6371 }
6372 client.asBinder().linkToDeath(this, 0);
6373 } catch (RemoteException e) {
6374 // The caller has died, so we can just forget about this.
6375 try {
6376 if (mInputMethodManager != null) {
6377 mInputMethodManager.removeClient(client);
6378 }
6379 } catch (RemoteException ee) {
6380 }
6381 } finally {
6382 Binder.restoreCallingIdentity(ident);
6383 }
6384 }
Romain Guy06882f82009-06-10 13:36:04 -07006385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 @Override
6387 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6388 throws RemoteException {
6389 try {
6390 return super.onTransact(code, data, reply, flags);
6391 } catch (RuntimeException e) {
6392 // Log all 'real' exceptions thrown to the caller
6393 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006394 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 }
6396 throw e;
6397 }
6398 }
6399
6400 public void binderDied() {
6401 // Note: it is safe to call in to the input method manager
6402 // here because we are not holding our lock.
6403 try {
6404 if (mInputMethodManager != null) {
6405 mInputMethodManager.removeClient(mClient);
6406 }
6407 } catch (RemoteException e) {
6408 }
6409 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006410 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006411 mClientDead = true;
6412 killSessionLocked();
6413 }
6414 }
6415
6416 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006417 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6418 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6419 outInputChannel);
6420 }
6421
6422 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006423 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006424 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 }
Romain Guy06882f82009-06-10 13:36:04 -07006426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006427 public void remove(IWindow window) {
6428 removeWindow(this, window);
6429 }
Romain Guy06882f82009-06-10 13:36:04 -07006430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006431 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6432 int requestedWidth, int requestedHeight, int viewFlags,
6433 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006434 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006435 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6436 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006438 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006439 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6440 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 }
Romain Guy06882f82009-06-10 13:36:04 -07006442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 public void setTransparentRegion(IWindow window, Region region) {
6444 setTransparentRegionWindow(this, window, region);
6445 }
Romain Guy06882f82009-06-10 13:36:04 -07006446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 public void setInsets(IWindow window, int touchableInsets,
6448 Rect contentInsets, Rect visibleInsets) {
6449 setInsetsWindow(this, window, touchableInsets, contentInsets,
6450 visibleInsets);
6451 }
Romain Guy06882f82009-06-10 13:36:04 -07006452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6454 getWindowDisplayFrame(this, window, outDisplayFrame);
6455 }
Romain Guy06882f82009-06-10 13:36:04 -07006456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006457 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006458 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 TAG, "IWindow finishDrawing called for " + window);
6460 finishDrawingWindow(this, window);
6461 }
6462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006463 public void setInTouchMode(boolean mode) {
6464 synchronized(mWindowMap) {
6465 mInTouchMode = mode;
6466 }
6467 }
6468
6469 public boolean getInTouchMode() {
6470 synchronized(mWindowMap) {
6471 return mInTouchMode;
6472 }
6473 }
6474
6475 public boolean performHapticFeedback(IWindow window, int effectId,
6476 boolean always) {
6477 synchronized(mWindowMap) {
6478 long ident = Binder.clearCallingIdentity();
6479 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006480 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006481 windowForClientLocked(this, window, true),
6482 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006483 } finally {
6484 Binder.restoreCallingIdentity(ident);
6485 }
6486 }
6487 }
Romain Guy06882f82009-06-10 13:36:04 -07006488
Christopher Tatea53146c2010-09-07 11:57:52 -07006489 /* Drag/drop */
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006490 public IBinder prepareDrag(IWindow window, int flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006491 int width, int height, Surface outSurface) {
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006492 return prepareDragSurface(window, mSurfaceSession, flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006493 width, height, outSurface);
6494 }
6495
6496 public boolean performDrag(IWindow window, IBinder dragToken,
6497 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6498 ClipData data) {
6499 if (DEBUG_DRAG) {
6500 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6501 }
6502
6503 synchronized (mWindowMap) {
6504 if (mDragState == null) {
6505 Slog.w(TAG, "No drag prepared");
6506 throw new IllegalStateException("performDrag() without prepareDrag()");
6507 }
6508
6509 if (dragToken != mDragState.mToken) {
6510 Slog.w(TAG, "Performing mismatched drag");
6511 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6512 }
6513
6514 WindowState callingWin = windowForClientLocked(null, window, false);
6515 if (callingWin == null) {
6516 Slog.w(TAG, "Bad requesting window " + window);
6517 return false; // !!! TODO: throw here?
6518 }
6519
6520 // !!! TODO: if input is not still focused on the initiating window, fail
6521 // the drag initiation (e.g. an alarm window popped up just as the application
6522 // called performDrag()
6523
6524 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6525
Christopher Tate2c095f32010-10-04 14:13:40 -07006526 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6527 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006528
Chris Tateb478f462010-10-15 16:02:26 -07006529 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6530 // the actual drag event dispatch stuff in the dragstate
6531
Christopher Tatea53146c2010-09-07 11:57:52 -07006532 mDragState.register();
6533 mInputMonitor.updateInputWindowsLw();
Chris Tateef70a072010-10-22 19:10:34 -07006534 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6535 mDragState.mServerChannel)) {
6536 Slog.e(TAG, "Unable to transfer touch focus");
6537 mDragState.unregister();
6538 mDragState = null;
6539 mInputMonitor.updateInputWindowsLw();
6540 return false;
6541 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006542
6543 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006544 mDragState.mCurrentX = touchX;
6545 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006546 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006547
6548 // remember the thumb offsets for later
6549 mDragState.mThumbOffsetX = thumbCenterX;
6550 mDragState.mThumbOffsetY = thumbCenterY;
6551
6552 // Make the surface visible at the proper location
6553 final Surface surface = mDragState.mSurface;
Chris Tateb478f462010-10-15 16:02:26 -07006554 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006555 try {
6556 surface.setPosition((int)(touchX - thumbCenterX),
6557 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006558 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006559 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006560 surface.show();
6561 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006562 Surface.closeTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006563 }
6564 }
6565
6566 return true; // success!
6567 }
6568
Chris Tated4533f142010-10-19 15:15:08 -07006569 public void reportDropResult(IWindow window, boolean consumed) {
6570 IBinder token = window.asBinder();
6571 if (DEBUG_DRAG) {
6572 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6573 }
6574
6575 synchronized (mWindowMap) {
Christopher Tateccd24de2011-01-12 15:02:55 -08006576 long ident = Binder.clearCallingIdentity();
6577 try {
6578 if (mDragState.mToken != token) {
6579 Slog.w(TAG, "Invalid drop-result claim by " + window);
6580 throw new IllegalStateException("reportDropResult() by non-recipient");
6581 }
6582
6583 // The right window has responded, even if it's no longer around,
6584 // so be sure to halt the timeout even if the later WindowState
6585 // lookup fails.
6586 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6587 WindowState callingWin = windowForClientLocked(null, window, false);
6588 if (callingWin == null) {
6589 Slog.w(TAG, "Bad result-reporting window " + window);
6590 return; // !!! TODO: throw here?
6591 }
6592
6593 mDragState.mDragResult = consumed;
6594 mDragState.endDragLw();
6595 } finally {
6596 Binder.restoreCallingIdentity(ident);
Chris Tated4533f142010-10-19 15:15:08 -07006597 }
Chris Tated4533f142010-10-19 15:15:08 -07006598 }
6599 }
6600
Christopher Tatea53146c2010-09-07 11:57:52 -07006601 public void dragRecipientEntered(IWindow window) {
6602 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006603 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006604 }
6605 }
6606
6607 public void dragRecipientExited(IWindow window) {
6608 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006609 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006610 }
6611 }
6612
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006613 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006614 synchronized(mWindowMap) {
6615 long ident = Binder.clearCallingIdentity();
6616 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006617 setWindowWallpaperPositionLocked(
6618 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006619 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006620 } finally {
6621 Binder.restoreCallingIdentity(ident);
6622 }
6623 }
6624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006625
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006626 public void wallpaperOffsetsComplete(IBinder window) {
6627 WindowManagerService.this.wallpaperOffsetsComplete(window);
6628 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006629
Dianne Hackborn75804932009-10-20 20:15:20 -07006630 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6631 int z, Bundle extras, boolean sync) {
6632 synchronized(mWindowMap) {
6633 long ident = Binder.clearCallingIdentity();
6634 try {
6635 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006636 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006637 action, x, y, z, extras, sync);
6638 } finally {
6639 Binder.restoreCallingIdentity(ident);
6640 }
6641 }
6642 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006643
Dianne Hackborn75804932009-10-20 20:15:20 -07006644 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6645 WindowManagerService.this.wallpaperCommandComplete(window, result);
6646 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 void windowAddedLocked() {
6649 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006650 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 TAG, "First window added to " + this + ", creating SurfaceSession");
6652 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006653 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006654 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006655 mSessions.add(this);
6656 }
6657 mNumWindow++;
6658 }
6659
6660 void windowRemovedLocked() {
6661 mNumWindow--;
6662 killSessionLocked();
6663 }
Romain Guy06882f82009-06-10 13:36:04 -07006664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006665 void killSessionLocked() {
6666 if (mNumWindow <= 0 && mClientDead) {
6667 mSessions.remove(this);
6668 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006669 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006670 TAG, "Last window removed from " + this
6671 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006672 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006673 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006674 try {
6675 mSurfaceSession.kill();
6676 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006677 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 + mSurfaceSession + " in session " + this
6679 + ": " + e.toString());
6680 }
6681 mSurfaceSession = null;
6682 }
6683 }
6684 }
Romain Guy06882f82009-06-10 13:36:04 -07006685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006687 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6688 pw.print(" mClientDead="); pw.print(mClientDead);
6689 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 }
6691
6692 @Override
6693 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006694 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 }
6696 }
6697
6698 // -------------------------------------------------------------
6699 // Client Window State
6700 // -------------------------------------------------------------
6701
6702 private final class WindowState implements WindowManagerPolicy.WindowState {
6703 final Session mSession;
6704 final IWindow mClient;
6705 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006706 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 AppWindowToken mAppToken;
6708 AppWindowToken mTargetAppToken;
6709 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6710 final DeathRecipient mDeathRecipient;
6711 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006712 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 final int mBaseLayer;
6714 final int mSubLayer;
6715 final boolean mLayoutAttached;
6716 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006717 final boolean mIsWallpaper;
6718 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 int mViewVisibility;
6720 boolean mPolicyVisibility = true;
6721 boolean mPolicyVisibilityAfterAnim = true;
6722 boolean mAppFreezing;
6723 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006724 boolean mReportDestroySurface;
6725 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006726 boolean mAttachedHidden; // is our parent window hidden?
6727 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006728 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006729 int mRequestedWidth;
6730 int mRequestedHeight;
6731 int mLastRequestedWidth;
6732 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006733 int mLayer;
6734 int mAnimLayer;
6735 int mLastLayer;
6736 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006737 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006738 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006740 int mLayoutSeq = -1;
6741
6742 Configuration mConfiguration = null;
6743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 // Actual frame shown on-screen (may be modified by animation)
6745 final Rect mShownFrame = new Rect();
6746 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006748 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006749 * Set when we have changed the size of the surface, to know that
6750 * we must tell them application to resize (and thus redraw itself).
6751 */
6752 boolean mSurfaceResized;
6753
6754 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 * Insets that determine the actually visible area
6756 */
6757 final Rect mVisibleInsets = new Rect();
6758 final Rect mLastVisibleInsets = new Rect();
6759 boolean mVisibleInsetsChanged;
6760
6761 /**
6762 * Insets that are covered by system windows
6763 */
6764 final Rect mContentInsets = new Rect();
6765 final Rect mLastContentInsets = new Rect();
6766 boolean mContentInsetsChanged;
6767
6768 /**
6769 * Set to true if we are waiting for this window to receive its
6770 * given internal insets before laying out other windows based on it.
6771 */
6772 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774 /**
6775 * These are the content insets that were given during layout for
6776 * this window, to be applied to windows behind it.
6777 */
6778 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 /**
6781 * These are the visible insets that were given during layout for
6782 * this window, to be applied to windows behind it.
6783 */
6784 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006786 /**
6787 * Flag indicating whether the touchable region should be adjusted by
6788 * the visible insets; if false the area outside the visible insets is
6789 * NOT touchable, so we must use those to adjust the frame during hit
6790 * tests.
6791 */
6792 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794 // Current transformation being applied.
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08006795 boolean mHaveMatrix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6797 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6798 float mHScale=1, mVScale=1;
6799 float mLastHScale=1, mLastVScale=1;
6800 final Matrix mTmpMatrix = new Matrix();
6801
6802 // "Real" frame that the application sees.
6803 final Rect mFrame = new Rect();
6804 final Rect mLastFrame = new Rect();
6805
6806 final Rect mContainingFrame = new Rect();
6807 final Rect mDisplayFrame = new Rect();
6808 final Rect mContentFrame = new Rect();
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006809 final Rect mParentFrame = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 final Rect mVisibleFrame = new Rect();
6811
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006812 boolean mContentChanged;
6813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 float mShownAlpha = 1;
6815 float mAlpha = 1;
6816 float mLastAlpha = 1;
6817
6818 // Set to true if, when the window gets displayed, it should perform
6819 // an enter animation.
6820 boolean mEnterAnimationPending;
6821
6822 // Currently running animation.
6823 boolean mAnimating;
6824 boolean mLocalAnimating;
6825 Animation mAnimation;
6826 boolean mAnimationIsEntrance;
6827 boolean mHasTransformation;
6828 boolean mHasLocalTransformation;
6829 final Transformation mTransformation = new Transformation();
6830
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006831 // If a window showing a wallpaper: the requested offset for the
6832 // wallpaper; if a wallpaper window: the currently applied offset.
6833 float mWallpaperX = -1;
6834 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006835
6836 // If a window showing a wallpaper: what fraction of the offset
6837 // range corresponds to a full virtual screen.
6838 float mWallpaperXStep = -1;
6839 float mWallpaperYStep = -1;
6840
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006841 // Wallpaper windows: pixels offset based on above variables.
6842 int mXOffset;
6843 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 // This is set after IWindowSession.relayout() has been called at
6846 // least once for the window. It allows us to detect the situation
6847 // where we don't yet have a surface, but should have one soon, so
6848 // we can give the window focus before waiting for the relayout.
6849 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 // This is set after the Surface has been created but before the
6852 // window has been drawn. During this time the surface is hidden.
6853 boolean mDrawPending;
6854
6855 // This is set after the window has finished drawing for the first
6856 // time but before its surface is shown. The surface will be
6857 // displayed when the next layout is run.
6858 boolean mCommitDrawPending;
6859
6860 // This is set during the time after the window's drawing has been
6861 // committed, and before its surface is actually shown. It is used
6862 // to delay showing the surface until all windows in a token are ready
6863 // to be shown.
6864 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 // Set when the window has been shown in the screen the first time.
6867 boolean mHasDrawn;
6868
6869 // Currently running an exit animation?
6870 boolean mExiting;
6871
6872 // Currently on the mDestroySurface list?
6873 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 // Completely remove from window manager after exit animation?
6876 boolean mRemoveOnExit;
6877
6878 // Set when the orientation is changing and this window has not yet
6879 // been updated for the new orientation.
6880 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 // Is this window now (or just being) removed?
6883 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006884
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006885 // Temp for keeping track of windows that have been removed when
6886 // rebuilding window list.
6887 boolean mRebuilding;
6888
Dianne Hackborn16064f92010-03-25 00:47:24 -07006889 // For debugging, this is the last information given to the surface flinger.
6890 boolean mSurfaceShown;
6891 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6892 int mSurfaceLayer;
6893 float mSurfaceAlpha;
6894
Jeff Brown928e0542011-01-10 11:17:36 -08006895 // Input channel and input window handle used by the input dispatcher.
6896 InputWindowHandle mInputWindowHandle;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006897 InputChannel mInputChannel;
6898
Mattias Petersson1622eee2010-12-21 10:15:11 +01006899 // Used to improve performance of toString()
6900 String mStringNameCache;
6901 CharSequence mLastTitle;
6902 boolean mWasPaused;
6903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 WindowState(Session s, IWindow c, WindowToken token,
6905 WindowState attachedWindow, WindowManager.LayoutParams a,
6906 int viewVisibility) {
6907 mSession = s;
6908 mClient = c;
6909 mToken = token;
6910 mAttrs.copyFrom(a);
6911 mViewVisibility = viewVisibility;
6912 DeathRecipient deathRecipient = new DeathRecipient();
6913 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006914 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006915 TAG, "Window " + this + " client=" + c.asBinder()
6916 + " token=" + token + " (" + mAttrs.token + ")");
6917 try {
6918 c.asBinder().linkToDeath(deathRecipient, 0);
6919 } catch (RemoteException e) {
6920 mDeathRecipient = null;
6921 mAttachedWindow = null;
6922 mLayoutAttached = false;
6923 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006924 mIsWallpaper = false;
6925 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 mBaseLayer = 0;
6927 mSubLayer = 0;
6928 return;
6929 }
6930 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6933 mAttrs.type <= LAST_SUB_WINDOW)) {
6934 // The multiplier here is to reserve space for multiple
6935 // windows in the same type layer.
6936 mBaseLayer = mPolicy.windowTypeToLayerLw(
6937 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6938 + TYPE_LAYER_OFFSET;
6939 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6940 mAttachedWindow = attachedWindow;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006941 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 mAttachedWindow.mChildWindows.add(this);
6943 mLayoutAttached = mAttrs.type !=
6944 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6945 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6946 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006947 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6948 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006949 } else {
6950 // The multiplier here is to reserve space for multiple
6951 // windows in the same type layer.
6952 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6953 * TYPE_LAYER_MULTIPLIER
6954 + TYPE_LAYER_OFFSET;
6955 mSubLayer = 0;
6956 mAttachedWindow = null;
6957 mLayoutAttached = false;
6958 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6959 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006960 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6961 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 }
6963
6964 WindowState appWin = this;
6965 while (appWin.mAttachedWindow != null) {
6966 appWin = mAttachedWindow;
6967 }
6968 WindowToken appToken = appWin.mToken;
6969 while (appToken.appWindowToken == null) {
6970 WindowToken parent = mTokenMap.get(appToken.token);
6971 if (parent == null || appToken == parent) {
6972 break;
6973 }
6974 appToken = parent;
6975 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006976 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 mAppToken = appToken.appWindowToken;
6978
6979 mSurface = null;
6980 mRequestedWidth = 0;
6981 mRequestedHeight = 0;
6982 mLastRequestedWidth = 0;
6983 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006984 mXOffset = 0;
6985 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006986 mLayer = 0;
6987 mAnimLayer = 0;
6988 mLastLayer = 0;
Jeff Brown928e0542011-01-10 11:17:36 -08006989 mInputWindowHandle = new InputWindowHandle(
6990 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 }
6992
6993 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006994 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 TAG, "Attaching " + this + " token=" + mToken
6996 + ", list=" + mToken.windows);
6997 mSession.windowAddedLocked();
6998 }
6999
7000 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7001 mHaveFrame = true;
7002
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007003 final Rect container = mContainingFrame;
7004 container.set(pf);
7005
7006 final Rect display = mDisplayFrame;
7007 display.set(df);
7008
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007009 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007010 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007011 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7012 display.intersect(mCompatibleScreenFrame);
7013 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007014 }
7015
7016 final int pw = container.right - container.left;
7017 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018
7019 int w,h;
7020 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7021 w = mAttrs.width < 0 ? pw : mAttrs.width;
7022 h = mAttrs.height< 0 ? ph : mAttrs.height;
7023 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007024 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7025 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 }
Romain Guy06882f82009-06-10 13:36:04 -07007027
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007028 if (!mParentFrame.equals(pf)) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007029 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
7030 // + " to " + pf);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007031 mParentFrame.set(pf);
7032 mContentChanged = true;
7033 }
7034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007035 final Rect content = mContentFrame;
7036 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007038 final Rect visible = mVisibleFrame;
7039 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007042 final int fw = frame.width();
7043 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7046 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7047
7048 Gravity.apply(mAttrs.gravity, w, h, container,
7049 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7050 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7051
7052 //System.out.println("Out: " + mFrame);
7053
7054 // Now make sure the window fits in the overall display.
7055 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 // Make sure the content and visible frames are inside of the
7058 // final window frame.
7059 if (content.left < frame.left) content.left = frame.left;
7060 if (content.top < frame.top) content.top = frame.top;
7061 if (content.right > frame.right) content.right = frame.right;
7062 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7063 if (visible.left < frame.left) visible.left = frame.left;
7064 if (visible.top < frame.top) visible.top = frame.top;
7065 if (visible.right > frame.right) visible.right = frame.right;
7066 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 final Rect contentInsets = mContentInsets;
7069 contentInsets.left = content.left-frame.left;
7070 contentInsets.top = content.top-frame.top;
7071 contentInsets.right = frame.right-content.right;
7072 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 final Rect visibleInsets = mVisibleInsets;
7075 visibleInsets.left = visible.left-frame.left;
7076 visibleInsets.top = visible.top-frame.top;
7077 visibleInsets.right = frame.right-visible.right;
7078 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007079
Dianne Hackborn284ac932009-08-28 10:34:25 -07007080 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7081 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007082 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007083 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 if (localLOGV) {
7086 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7087 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007088 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 + mRequestedWidth + ", mRequestedheight="
7090 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7091 + "): frame=" + mFrame.toShortString()
7092 + " ci=" + contentInsets.toShortString()
7093 + " vi=" + visibleInsets.toShortString());
7094 //}
7095 }
7096 }
Romain Guy06882f82009-06-10 13:36:04 -07007097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 public Rect getFrameLw() {
7099 return mFrame;
7100 }
7101
7102 public Rect getShownFrameLw() {
7103 return mShownFrame;
7104 }
7105
7106 public Rect getDisplayFrameLw() {
7107 return mDisplayFrame;
7108 }
7109
7110 public Rect getContentFrameLw() {
7111 return mContentFrame;
7112 }
7113
7114 public Rect getVisibleFrameLw() {
7115 return mVisibleFrame;
7116 }
7117
7118 public boolean getGivenInsetsPendingLw() {
7119 return mGivenInsetsPending;
7120 }
7121
7122 public Rect getGivenContentInsetsLw() {
7123 return mGivenContentInsets;
7124 }
Romain Guy06882f82009-06-10 13:36:04 -07007125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007126 public Rect getGivenVisibleInsetsLw() {
7127 return mGivenVisibleInsets;
7128 }
Romain Guy06882f82009-06-10 13:36:04 -07007129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007130 public WindowManager.LayoutParams getAttrs() {
7131 return mAttrs;
7132 }
7133
7134 public int getSurfaceLayer() {
7135 return mLayer;
7136 }
Romain Guy06882f82009-06-10 13:36:04 -07007137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 public IApplicationToken getAppToken() {
7139 return mAppToken != null ? mAppToken.appToken : null;
7140 }
Jeff Brown349703e2010-06-22 01:27:15 -07007141
7142 public long getInputDispatchingTimeoutNanos() {
7143 return mAppToken != null
7144 ? mAppToken.inputDispatchingTimeoutNanos
7145 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007147
7148 public boolean hasAppShownWindows() {
7149 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7150 }
7151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007152 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007153 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007154 TAG, "Setting animation in " + this + ": " + anim);
7155 mAnimating = false;
7156 mLocalAnimating = false;
7157 mAnimation = anim;
7158 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7159 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7160 }
7161
7162 public void clearAnimation() {
7163 if (mAnimation != null) {
7164 mAnimating = true;
7165 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007166 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 mAnimation = null;
7168 }
7169 }
Romain Guy06882f82009-06-10 13:36:04 -07007170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 Surface createSurfaceLocked() {
7172 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007173 mReportDestroySurface = false;
7174 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007175 mDrawPending = true;
7176 mCommitDrawPending = false;
7177 mReadyToShow = false;
7178 if (mAppToken != null) {
7179 mAppToken.allDrawn = false;
7180 }
7181
7182 int flags = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183
7184 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7185 flags |= Surface.SECURE;
7186 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007187 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 TAG, "Creating surface in session "
7189 + mSession.mSurfaceSession + " window " + this
7190 + " w=" + mFrame.width()
7191 + " h=" + mFrame.height() + " format="
7192 + mAttrs.format + " flags=" + flags);
7193
7194 int w = mFrame.width();
7195 int h = mFrame.height();
7196 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7197 // for a scaled surface, we always want the requested
7198 // size.
7199 w = mRequestedWidth;
7200 h = mRequestedHeight;
7201 }
7202
Romain Guy9825ec62009-10-01 00:58:09 -07007203 // Something is wrong and SurfaceFlinger will not like this,
7204 // try to revert to sane values
7205 if (w <= 0) w = 1;
7206 if (h <= 0) h = 1;
7207
Dianne Hackborn16064f92010-03-25 00:47:24 -07007208 mSurfaceShown = false;
7209 mSurfaceLayer = 0;
7210 mSurfaceAlpha = 1;
7211 mSurfaceX = 0;
7212 mSurfaceY = 0;
7213 mSurfaceW = w;
7214 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 try {
Romain Guyd10cd572010-10-10 13:33:22 -07007216 final boolean isHwAccelerated = (mAttrs.flags &
7217 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
7218 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
7219 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
7220 flags |= Surface.OPAQUE;
7221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007222 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007223 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007224 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07007225 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007226 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007227 + mSurface + " IN SESSION "
7228 + mSession.mSurfaceSession
7229 + ": pid=" + mSession.mPid + " format="
7230 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007231 + Integer.toHexString(flags)
7232 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007234 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007235 reclaimSomeSurfaceMemoryLocked(this, "create");
7236 return null;
7237 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007238 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007239 return null;
7240 }
Romain Guy06882f82009-06-10 13:36:04 -07007241
Joe Onorato8a9b2202010-02-26 18:56:32 -08007242 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 TAG, "Got surface: " + mSurface
7244 + ", set left=" + mFrame.left + " top=" + mFrame.top
7245 + ", animLayer=" + mAnimLayer);
7246 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007247 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007248 if (SHOW_TRANSACTIONS) logSurface(this,
7249 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7250 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7251 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007252 }
7253 Surface.openTransaction();
7254 try {
7255 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007256 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007257 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007258 mSurface.setPosition(mSurfaceX, mSurfaceY);
7259 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007260 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007261 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007262 mSurface.hide();
7263 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007264 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007265 mSurface.setFlags(Surface.SURFACE_DITHER,
7266 Surface.SURFACE_DITHER);
7267 }
7268 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007269 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7271 }
7272 mLastHidden = true;
7273 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007274 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 Surface.closeTransaction();
7276 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007277 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007278 TAG, "Created surface " + this);
7279 }
7280 return mSurface;
7281 }
Romain Guy06882f82009-06-10 13:36:04 -07007282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007283 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007284 if (mAppToken != null && this == mAppToken.startingWindow) {
7285 mAppToken.startingDisplayed = false;
7286 }
Romain Guy06882f82009-06-10 13:36:04 -07007287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007289 mDrawPending = false;
7290 mCommitDrawPending = false;
7291 mReadyToShow = false;
7292
7293 int i = mChildWindows.size();
7294 while (i > 0) {
7295 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007296 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007297 c.mAttachedHidden = true;
7298 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007299
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007300 if (mReportDestroySurface) {
7301 mReportDestroySurface = false;
7302 mSurfacePendingDestroy = true;
7303 try {
7304 mClient.dispatchGetNewSurface();
7305 // We'll really destroy on the next time around.
7306 return;
7307 } catch (RemoteException e) {
7308 }
7309 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007312 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007313 RuntimeException e = null;
7314 if (!HIDE_STACK_CRAWLS) {
7315 e = new RuntimeException();
7316 e.fillInStackTrace();
7317 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007318 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007319 + mSurface + ", session " + mSession, e);
7320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007322 RuntimeException e = null;
7323 if (!HIDE_STACK_CRAWLS) {
7324 e = new RuntimeException();
7325 e.fillInStackTrace();
7326 }
7327 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007328 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007329 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007331 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 + " surface " + mSurface + " session " + mSession
7333 + ": " + e.toString());
7334 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007335
Dianne Hackborn16064f92010-03-25 00:47:24 -07007336 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007338 }
7339 }
7340
7341 boolean finishDrawingLocked() {
7342 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007343 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 TAG, "finishDrawingLocked: " + mSurface);
7345 mCommitDrawPending = true;
7346 mDrawPending = false;
7347 return true;
7348 }
7349 return false;
7350 }
7351
7352 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007353 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007354 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007355 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007356 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007357 }
7358 mCommitDrawPending = false;
7359 mReadyToShow = true;
7360 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7361 final AppWindowToken atoken = mAppToken;
7362 if (atoken == null || atoken.allDrawn || starting) {
7363 performShowLocked();
7364 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007365 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 }
7367
7368 // This must be called while inside a transaction.
7369 boolean performShowLocked() {
7370 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007371 RuntimeException e = null;
7372 if (!HIDE_STACK_CRAWLS) {
7373 e = new RuntimeException();
7374 e.fillInStackTrace();
7375 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007376 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7378 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7379 }
7380 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007381 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7382 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007383 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 + " during animation: policyVis=" + mPolicyVisibility
7385 + " attHidden=" + mAttachedHidden
7386 + " tok.hiddenRequested="
7387 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007388 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 + (mAppToken != null ? mAppToken.hidden : false)
7390 + " animating=" + mAnimating
7391 + " tok animating="
7392 + (mAppToken != null ? mAppToken.animating : false));
7393 if (!showSurfaceRobustlyLocked(this)) {
7394 return false;
7395 }
7396 mLastAlpha = -1;
7397 mHasDrawn = true;
7398 mLastHidden = false;
7399 mReadyToShow = false;
7400 enableScreenIfNeededLocked();
7401
7402 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007404 int i = mChildWindows.size();
7405 while (i > 0) {
7406 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007407 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007408 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007410 if (c.mSurface != null) {
7411 c.performShowLocked();
7412 // It hadn't been shown, which means layout not
7413 // performed on it, so now we want to make sure to
7414 // do a layout. If called from within the transaction
7415 // loop, this will cause it to restart with a new
7416 // layout.
7417 mLayoutNeeded = true;
7418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007419 }
7420 }
Romain Guy06882f82009-06-10 13:36:04 -07007421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007422 if (mAttrs.type != TYPE_APPLICATION_STARTING
7423 && mAppToken != null) {
7424 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007425
Dianne Hackborn248b1882009-09-16 16:46:44 -07007426 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007427 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007428 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007430 // If this initial window is animating, stop it -- we
7431 // will do an animation to reveal it from behind the
7432 // starting window, so there is no need for it to also
7433 // be doing its own stuff.
7434 if (mAnimation != null) {
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007435 mAnimation.cancel();
Dianne Hackborn248b1882009-09-16 16:46:44 -07007436 mAnimation = null;
7437 // Make sure we clean up the animation.
7438 mAnimating = true;
7439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007440 mFinishedStarting.add(mAppToken);
7441 mH.sendEmptyMessage(H.FINISHED_STARTING);
7442 }
7443 mAppToken.updateReportedVisibilityLocked();
7444 }
7445 }
7446 return true;
7447 }
Romain Guy06882f82009-06-10 13:36:04 -07007448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 // This must be called while inside a transaction. Returns true if
7450 // there is more animation to run.
7451 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007452 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7456 mHasTransformation = true;
7457 mHasLocalTransformation = true;
7458 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007459 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 TAG, "Starting animation in " + this +
7461 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7462 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7463 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7464 mAnimation.setStartTime(currentTime);
7465 mLocalAnimating = true;
7466 mAnimating = true;
7467 }
7468 mTransformation.clear();
7469 final boolean more = mAnimation.getTransformation(
7470 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007471 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007472 TAG, "Stepped animation in " + this +
7473 ": more=" + more + ", xform=" + mTransformation);
7474 if (more) {
7475 // we're not done!
7476 return true;
7477 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007478 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 TAG, "Finished animation in " + this +
7480 " @ " + currentTime);
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007481
7482 if (mAnimation != null) {
7483 mAnimation.cancel();
7484 mAnimation = null;
7485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 //WindowManagerService.this.dump();
7487 }
7488 mHasLocalTransformation = false;
7489 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007490 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 // When our app token is animating, we kind-of pretend like
7492 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7493 // part of this check means that we will only do this if
7494 // our window is not currently exiting, or it is not
7495 // locally animating itself. The idea being that one that
7496 // is exiting and doing a local animation should be removed
7497 // once that animation is done.
7498 mAnimating = true;
7499 mHasTransformation = true;
7500 mTransformation.clear();
7501 return false;
7502 } else if (mHasTransformation) {
7503 // Little trick to get through the path below to act like
7504 // we have finished an animation.
7505 mAnimating = true;
7506 } else if (isAnimating()) {
7507 mAnimating = true;
7508 }
7509 } else if (mAnimation != null) {
7510 // If the display is frozen, and there is a pending animation,
7511 // clear it and make sure we run the cleanup code.
7512 mAnimating = true;
7513 mLocalAnimating = true;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007514 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007515 mAnimation = null;
7516 }
Romain Guy06882f82009-06-10 13:36:04 -07007517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 if (!mAnimating && !mLocalAnimating) {
7519 return false;
7520 }
7521
Joe Onorato8a9b2202010-02-26 18:56:32 -08007522 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007523 TAG, "Animation done in " + this + ": exiting=" + mExiting
7524 + ", reportedVisible="
7525 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 mAnimating = false;
7528 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007529 if (mAnimation != null) {
7530 mAnimation.cancel();
7531 mAnimation = null;
7532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 mAnimLayer = mLayer;
7534 if (mIsImWindow) {
7535 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007536 } else if (mIsWallpaper) {
7537 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007539 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007540 + " anim layer: " + mAnimLayer);
7541 mHasTransformation = false;
7542 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007543 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7544 if (DEBUG_VISIBILITY) {
7545 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7546 + mPolicyVisibilityAfterAnim);
7547 }
7548 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7549 if (!mPolicyVisibility) {
7550 if (mCurrentFocus == this) {
7551 mFocusMayChange = true;
7552 }
7553 // Window is no longer visible -- make sure if we were waiting
7554 // for it to be displayed before enabling the display, that
7555 // we allow the display to be enabled now.
7556 enableScreenIfNeededLocked();
7557 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 mTransformation.clear();
7560 if (mHasDrawn
7561 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7562 && mAppToken != null
7563 && mAppToken.firstWindowDrawn
7564 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007565 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 + mToken + ": first real window done animating");
7567 mFinishedStarting.add(mAppToken);
7568 mH.sendEmptyMessage(H.FINISHED_STARTING);
7569 }
Romain Guy06882f82009-06-10 13:36:04 -07007570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007571 finishExit();
7572
7573 if (mAppToken != null) {
7574 mAppToken.updateReportedVisibilityLocked();
7575 }
7576
7577 return false;
7578 }
7579
7580 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007581 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007582 TAG, "finishExit in " + this
7583 + ": exiting=" + mExiting
7584 + " remove=" + mRemoveOnExit
7585 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007587 final int N = mChildWindows.size();
7588 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007589 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007590 }
Romain Guy06882f82009-06-10 13:36:04 -07007591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007592 if (!mExiting) {
7593 return;
7594 }
Romain Guy06882f82009-06-10 13:36:04 -07007595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007596 if (isWindowAnimating()) {
7597 return;
7598 }
7599
Joe Onorato8a9b2202010-02-26 18:56:32 -08007600 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007601 TAG, "Exit animation finished in " + this
7602 + ": remove=" + mRemoveOnExit);
7603 if (mSurface != null) {
7604 mDestroySurface.add(this);
7605 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007606 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007607 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007608 try {
7609 mSurface.hide();
7610 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007611 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007612 }
7613 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007614 }
7615 mExiting = false;
7616 if (mRemoveOnExit) {
7617 mPendingRemove.add(this);
7618 mRemoveOnExit = false;
7619 }
7620 }
Romain Guy06882f82009-06-10 13:36:04 -07007621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7623 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7624 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7625 if (dtdx < -.000001f || dtdx > .000001f) return false;
7626 if (dsdy < -.000001f || dsdy > .000001f) return false;
7627 return true;
7628 }
Romain Guy06882f82009-06-10 13:36:04 -07007629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007630 void computeShownFrameLocked() {
7631 final boolean selfTransformation = mHasLocalTransformation;
7632 Transformation attachedTransformation =
7633 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7634 ? mAttachedWindow.mTransformation : null;
7635 Transformation appTransformation =
7636 (mAppToken != null && mAppToken.hasTransformation)
7637 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007638
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007639 // Wallpapers are animated based on the "real" window they
7640 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007641 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007642 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007643 if (mWallpaperTarget.mHasLocalTransformation &&
7644 mWallpaperTarget.mAnimation != null &&
7645 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007646 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007647 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007648 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007649 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007650 }
7651 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007652 mWallpaperTarget.mAppToken.hasTransformation &&
7653 mWallpaperTarget.mAppToken.animation != null &&
7654 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007655 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007656 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007657 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007658 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007659 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007660 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007661
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007662 final boolean screenAnimation = mScreenRotationAnimation != null
7663 && mScreenRotationAnimation.isAnimating();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007664 if (selfTransformation || attachedTransformation != null
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007665 || appTransformation != null || screenAnimation) {
Romain Guy06882f82009-06-10 13:36:04 -07007666 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007667 final Rect frame = mFrame;
7668 final float tmpFloats[] = mTmpFloats;
7669 final Matrix tmpMatrix = mTmpMatrix;
7670
7671 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007672 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007674 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007675 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007676 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007677 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007678 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007679 }
7680 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007681 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007683 if (screenAnimation) {
7684 tmpMatrix.postConcat(
7685 mScreenRotationAnimation.getEnterTransformation().getMatrix());
7686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007687
7688 // "convert" it into SurfaceFlinger's format
7689 // (a 2x2 matrix + an offset)
7690 // Here we must not transform the position of the surface
7691 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007692 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007693
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007694 mHaveMatrix = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007695 tmpMatrix.getValues(tmpFloats);
7696 mDsDx = tmpFloats[Matrix.MSCALE_X];
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007697 mDtDx = tmpFloats[Matrix.MSKEW_Y];
7698 mDsDy = tmpFloats[Matrix.MSKEW_X];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007700 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7701 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 int w = frame.width();
7703 int h = frame.height();
7704 mShownFrame.set(x, y, x+w, y+h);
7705
7706 // Now set the alpha... but because our current hardware
7707 // can't do alpha transformation on a non-opaque surface,
7708 // turn it off if we are running an animation that is also
7709 // transforming since it is more important to have that
7710 // animation be smooth.
7711 mShownAlpha = mAlpha;
7712 if (!mLimitedAlphaCompositing
7713 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7714 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7715 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007716 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007717 if (selfTransformation) {
7718 mShownAlpha *= mTransformation.getAlpha();
7719 }
7720 if (attachedTransformation != null) {
7721 mShownAlpha *= attachedTransformation.getAlpha();
7722 }
7723 if (appTransformation != null) {
7724 mShownAlpha *= appTransformation.getAlpha();
7725 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007726 if (screenAnimation) {
7727 mShownAlpha *=
7728 mScreenRotationAnimation.getEnterTransformation().getAlpha();
7729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007730 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007731 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732 }
Romain Guy06882f82009-06-10 13:36:04 -07007733
Joe Onorato8a9b2202010-02-26 18:56:32 -08007734 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 TAG, "Continuing animation in " + this +
7736 ": " + mShownFrame +
7737 ", alpha=" + mTransformation.getAlpha());
7738 return;
7739 }
Romain Guy06882f82009-06-10 13:36:04 -07007740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007741 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007742 if (mXOffset != 0 || mYOffset != 0) {
7743 mShownFrame.offset(mXOffset, mYOffset);
7744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 mShownAlpha = mAlpha;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007746 mHaveMatrix = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007747 mDsDx = 1;
7748 mDtDx = 0;
7749 mDsDy = 0;
7750 mDtDy = 1;
7751 }
Romain Guy06882f82009-06-10 13:36:04 -07007752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 /**
7754 * Is this window visible? It is not visible if there is no
7755 * surface, or we are in the process of running an exit animation
7756 * that will remove the surface, or its app token has been hidden.
7757 */
7758 public boolean isVisibleLw() {
7759 final AppWindowToken atoken = mAppToken;
7760 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7761 && (atoken == null || !atoken.hiddenRequested)
7762 && !mExiting && !mDestroying;
7763 }
7764
7765 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007766 * Like {@link #isVisibleLw}, but also counts a window that is currently
7767 * "hidden" behind the keyguard as visible. This allows us to apply
7768 * things like window flags that impact the keyguard.
7769 * XXX I am starting to think we need to have ANOTHER visibility flag
7770 * for this "hidden behind keyguard" state rather than overloading
7771 * mPolicyVisibility. Ungh.
7772 */
7773 public boolean isVisibleOrBehindKeyguardLw() {
7774 final AppWindowToken atoken = mAppToken;
7775 return mSurface != null && !mAttachedHidden
7776 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007777 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007778 && !mExiting && !mDestroying;
7779 }
7780
7781 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 * Is this window visible, ignoring its app token? It is not visible
7783 * if there is no surface, or we are in the process of running an exit animation
7784 * that will remove the surface.
7785 */
7786 public boolean isWinVisibleLw() {
7787 final AppWindowToken atoken = mAppToken;
7788 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7789 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7790 && !mExiting && !mDestroying;
7791 }
7792
7793 /**
7794 * The same as isVisible(), but follows the current hidden state of
7795 * the associated app token, not the pending requested hidden state.
7796 */
7797 boolean isVisibleNow() {
7798 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007799 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007800 }
7801
7802 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007803 * Can this window possibly be a drag/drop target? The test here is
7804 * a combination of the above "visible now" with the check that the
7805 * Input Manager uses when discarding windows from input consideration.
7806 */
7807 boolean isPotentialDragTarget() {
7808 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7809 }
7810
7811 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007812 * Same as isVisible(), but we also count it as visible between the
7813 * call to IWindowSession.add() and the first relayout().
7814 */
7815 boolean isVisibleOrAdding() {
7816 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007817 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007818 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7819 && mPolicyVisibility && !mAttachedHidden
7820 && (atoken == null || !atoken.hiddenRequested)
7821 && !mExiting && !mDestroying;
7822 }
7823
7824 /**
7825 * Is this window currently on-screen? It is on-screen either if it
7826 * is visible or it is currently running an animation before no longer
7827 * being visible.
7828 */
7829 boolean isOnScreen() {
7830 final AppWindowToken atoken = mAppToken;
7831 if (atoken != null) {
7832 return mSurface != null && mPolicyVisibility && !mDestroying
7833 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007834 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 } else {
7836 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007837 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 }
7839 }
Romain Guy06882f82009-06-10 13:36:04 -07007840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 /**
7842 * Like isOnScreen(), but we don't return true if the window is part
7843 * of a transition that has not yet been started.
7844 */
7845 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007846 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007847 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007848 return false;
7849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007851 final boolean animating = atoken != null
7852 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007854 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7855 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007856 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 }
7858
7859 /** Is the window or its container currently animating? */
7860 boolean isAnimating() {
7861 final WindowState attached = mAttachedWindow;
7862 final AppWindowToken atoken = mAppToken;
7863 return mAnimation != null
7864 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007865 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007866 (atoken.animation != null
7867 || atoken.inPendingTransaction));
7868 }
7869
7870 /** Is this window currently animating? */
7871 boolean isWindowAnimating() {
7872 return mAnimation != null;
7873 }
7874
7875 /**
7876 * Like isOnScreen, but returns false if the surface hasn't yet
7877 * been drawn.
7878 */
7879 public boolean isDisplayedLw() {
7880 final AppWindowToken atoken = mAppToken;
7881 return mSurface != null && mPolicyVisibility && !mDestroying
7882 && !mDrawPending && !mCommitDrawPending
7883 && ((!mAttachedHidden &&
7884 (atoken == null || !atoken.hiddenRequested))
7885 || mAnimating);
7886 }
7887
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007888 /**
7889 * Returns true if the window has a surface that it has drawn a
7890 * complete UI in to.
7891 */
7892 public boolean isDrawnLw() {
7893 final AppWindowToken atoken = mAppToken;
7894 return mSurface != null && !mDestroying
7895 && !mDrawPending && !mCommitDrawPending;
7896 }
7897
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007898 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007899 * Return true if the window is opaque and fully drawn. This indicates
7900 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007901 */
7902 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007903 return (mAttrs.format == PixelFormat.OPAQUE
7904 || mAttrs.type == TYPE_WALLPAPER)
7905 && mSurface != null && mAnimation == null
7906 && (mAppToken == null || mAppToken.animation == null)
7907 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007908 }
7909
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007910 /**
7911 * Return whether this window is wanting to have a translation
7912 * animation applied to it for an in-progress move. (Only makes
7913 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
7914 */
7915 boolean shouldAnimateMove() {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007916 return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007917 && (mFrame.top != mLastFrame.top
7918 || mFrame.left != mLastFrame.left)
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007919 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007920 && mPolicy.isScreenOn();
7921 }
7922
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007923 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7924 return
7925 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007926 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7927 // only if it's visible
7928 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007929 // and only if the application fills the compatible screen
7930 mFrame.left <= mCompatibleScreenFrame.left &&
7931 mFrame.top <= mCompatibleScreenFrame.top &&
7932 mFrame.right >= mCompatibleScreenFrame.right &&
7933 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007934 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007935 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007936 }
7937
7938 boolean isFullscreen(int screenWidth, int screenHeight) {
7939 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007940 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007941 }
7942
7943 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007944 disposeInputChannel();
7945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 if (mAttachedWindow != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007947 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 mAttachedWindow.mChildWindows.remove(this);
7949 }
7950 destroySurfaceLocked();
7951 mSession.windowRemovedLocked();
7952 try {
7953 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7954 } catch (RuntimeException e) {
7955 // Ignore if it has already been removed (usually because
7956 // we are doing this as part of processing a death note.)
7957 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007958 }
7959
7960 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007961 if (mInputChannel != null) {
7962 mInputManager.unregisterInputChannel(mInputChannel);
7963
7964 mInputChannel.dispose();
7965 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 }
7968
7969 private class DeathRecipient implements IBinder.DeathRecipient {
7970 public void binderDied() {
7971 try {
7972 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007973 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007974 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 if (win != null) {
7976 removeWindowLocked(mSession, win);
7977 }
7978 }
7979 } catch (IllegalArgumentException ex) {
7980 // This will happen if the window has already been
7981 // removed.
7982 }
7983 }
7984 }
7985
7986 /** Returns true if this window desires key events. */
7987 public final boolean canReceiveKeys() {
7988 return isVisibleOrAdding()
7989 && (mViewVisibility == View.VISIBLE)
7990 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7991 }
7992
7993 public boolean hasDrawnLw() {
7994 return mHasDrawn;
7995 }
7996
7997 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007998 return showLw(doAnimation, true);
7999 }
8000
8001 boolean showLw(boolean doAnimation, boolean requestAnim) {
8002 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8003 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008005 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008006 if (doAnimation) {
8007 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8008 + mPolicyVisibility + " mAnimation=" + mAnimation);
8009 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8010 doAnimation = false;
8011 } else if (mPolicyVisibility && mAnimation == null) {
8012 // Check for the case where we are currently visible and
8013 // not animating; we do not want to do animation at such a
8014 // point to become visible when we already are.
8015 doAnimation = false;
8016 }
8017 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008018 mPolicyVisibility = true;
8019 mPolicyVisibilityAfterAnim = true;
8020 if (doAnimation) {
8021 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8022 }
8023 if (requestAnim) {
8024 requestAnimationLocked(0);
8025 }
8026 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008027 }
8028
8029 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008030 return hideLw(doAnimation, true);
8031 }
8032
8033 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008034 if (doAnimation) {
8035 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8036 doAnimation = false;
8037 }
8038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8040 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008041 if (!current) {
8042 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008044 if (doAnimation) {
8045 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8046 if (mAnimation == null) {
8047 doAnimation = false;
8048 }
8049 }
8050 if (doAnimation) {
8051 mPolicyVisibilityAfterAnim = false;
8052 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008053 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008054 mPolicyVisibilityAfterAnim = false;
8055 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008056 // Window is no longer visible -- make sure if we were waiting
8057 // for it to be displayed before enabling the display, that
8058 // we allow the display to be enabled now.
8059 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008060 if (mCurrentFocus == this) {
8061 mFocusMayChange = true;
8062 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008063 }
8064 if (requestAnim) {
8065 requestAnimationLocked(0);
8066 }
8067 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 }
8069
8070 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008071 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8072 pw.print(" mClient="); pw.println(mClient.asBinder());
8073 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8074 if (mAttachedWindow != null || mLayoutAttached) {
8075 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8076 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8077 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008078 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8079 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8080 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008081 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8082 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008083 }
8084 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8085 pw.print(" mSubLayer="); pw.print(mSubLayer);
8086 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8087 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8088 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8089 pw.print("="); pw.print(mAnimLayer);
8090 pw.print(" mLastLayer="); pw.println(mLastLayer);
8091 if (mSurface != null) {
8092 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008093 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8094 pw.print(" layer="); pw.print(mSurfaceLayer);
8095 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8096 pw.print(" rect=("); pw.print(mSurfaceX);
8097 pw.print(","); pw.print(mSurfaceY);
8098 pw.print(") "); pw.print(mSurfaceW);
8099 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008100 }
8101 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8102 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8103 if (mAppToken != null) {
8104 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8105 }
8106 if (mTargetAppToken != null) {
8107 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8108 }
8109 pw.print(prefix); pw.print("mViewVisibility=0x");
8110 pw.print(Integer.toHexString(mViewVisibility));
8111 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008112 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8113 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008114 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8115 pw.print(prefix); pw.print("mPolicyVisibility=");
8116 pw.print(mPolicyVisibility);
8117 pw.print(" mPolicyVisibilityAfterAnim=");
8118 pw.print(mPolicyVisibilityAfterAnim);
8119 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8120 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008121 if (!mRelayoutCalled) {
8122 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8123 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008124 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008125 pw.print(" h="); pw.print(mRequestedHeight);
8126 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008127 if (mXOffset != 0 || mYOffset != 0) {
8128 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8129 pw.print(" y="); pw.println(mYOffset);
8130 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008131 pw.print(prefix); pw.print("mGivenContentInsets=");
8132 mGivenContentInsets.printShortString(pw);
8133 pw.print(" mGivenVisibleInsets=");
8134 mGivenVisibleInsets.printShortString(pw);
8135 pw.println();
8136 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8137 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8138 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8139 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008140 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008141 pw.print(prefix); pw.print("mShownFrame=");
8142 mShownFrame.printShortString(pw);
8143 pw.print(" last="); mLastShownFrame.printShortString(pw);
8144 pw.println();
8145 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8146 pw.print(" last="); mLastFrame.printShortString(pw);
8147 pw.println();
8148 pw.print(prefix); pw.print("mContainingFrame=");
8149 mContainingFrame.printShortString(pw);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008150 pw.print(" mParentFrame=");
8151 mParentFrame.printShortString(pw);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008152 pw.print(" mDisplayFrame=");
8153 mDisplayFrame.printShortString(pw);
8154 pw.println();
8155 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8156 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8157 pw.println();
8158 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8159 pw.print(" last="); mLastContentInsets.printShortString(pw);
8160 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8161 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8162 pw.println();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008163 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8164 || mAnimation != null) {
8165 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8166 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8167 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8168 pw.print(" mAnimation="); pw.println(mAnimation);
8169 }
8170 if (mHasTransformation || mHasLocalTransformation) {
8171 pw.print(prefix); pw.print("XForm: has=");
8172 pw.print(mHasTransformation);
8173 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8174 pw.print(" "); mTransformation.printShortString(pw);
8175 pw.println();
8176 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008177 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8178 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8179 pw.print(" mAlpha="); pw.print(mAlpha);
8180 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8181 }
8182 if (mHaveMatrix) {
8183 pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
8184 pw.print(" mDtDx="); pw.print(mDtDx);
8185 pw.print(" mDsDy="); pw.print(mDsDy);
8186 pw.print(" mDtDy="); pw.println(mDtDy);
8187 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008188 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8189 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8190 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8191 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8192 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8193 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8194 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8195 pw.print(" mDestroying="); pw.print(mDestroying);
8196 pw.print(" mRemoved="); pw.println(mRemoved);
8197 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008198 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008199 pw.print(prefix); pw.print("mOrientationChanging=");
8200 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008201 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8202 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008203 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008204 if (mHScale != 1 || mVScale != 1) {
8205 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8206 pw.print(" mVScale="); pw.println(mVScale);
8207 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008208 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008209 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8210 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8211 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008212 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8213 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8214 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008217
8218 String makeInputChannelName() {
8219 return Integer.toHexString(System.identityHashCode(this))
8220 + " " + mAttrs.getTitle();
8221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222
8223 @Override
8224 public String toString() {
Mattias Petersson1622eee2010-12-21 10:15:11 +01008225 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
8226 || mWasPaused != mToken.paused) {
8227 mLastTitle = mAttrs.getTitle();
8228 mWasPaused = mToken.paused;
8229 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
8230 + " " + mLastTitle + " paused=" + mWasPaused + "}";
8231 }
8232 return mStringNameCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008233 }
8234 }
Romain Guy06882f82009-06-10 13:36:04 -07008235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008236 // -------------------------------------------------------------
8237 // Window Token State
8238 // -------------------------------------------------------------
8239
8240 class WindowToken {
8241 // The actual token.
8242 final IBinder token;
8243
8244 // The type of window this token is for, as per WindowManager.LayoutParams.
8245 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247 // Set if this token was explicitly added by a client, so should
8248 // not be removed when all windows are removed.
8249 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008250
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008251 // For printing.
8252 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254 // If this is an AppWindowToken, this is non-null.
8255 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008257 // All of the windows associated with this token.
8258 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8259
8260 // Is key dispatching paused for this token?
8261 boolean paused = false;
8262
8263 // Should this token's windows be hidden?
8264 boolean hidden;
8265
8266 // Temporary for finding which tokens no longer have visible windows.
8267 boolean hasVisible;
8268
Dianne Hackborna8f60182009-09-01 19:01:50 -07008269 // Set to true when this token is in a pending transaction where it
8270 // will be shown.
8271 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008272
Dianne Hackborna8f60182009-09-01 19:01:50 -07008273 // Set to true when this token is in a pending transaction where it
8274 // will be hidden.
8275 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008276
Dianne Hackborna8f60182009-09-01 19:01:50 -07008277 // Set to true when this token is in a pending transaction where its
8278 // windows will be put to the bottom of the list.
8279 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008280
Dianne Hackborna8f60182009-09-01 19:01:50 -07008281 // Set to true when this token is in a pending transaction where its
8282 // windows will be put to the top of the list.
8283 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 WindowToken(IBinder _token, int type, boolean _explicit) {
8286 token = _token;
8287 windowType = type;
8288 explicit = _explicit;
8289 }
8290
8291 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008292 pw.print(prefix); pw.print("token="); pw.println(token);
8293 pw.print(prefix); pw.print("windows="); pw.println(windows);
8294 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8295 pw.print(" hidden="); pw.print(hidden);
8296 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008297 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8298 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8299 pw.print(" waitingToHide="); pw.print(waitingToHide);
8300 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8301 pw.print(" sendingToTop="); pw.println(sendingToTop);
8302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008303 }
8304
8305 @Override
8306 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008307 if (stringName == null) {
8308 StringBuilder sb = new StringBuilder();
8309 sb.append("WindowToken{");
8310 sb.append(Integer.toHexString(System.identityHashCode(this)));
8311 sb.append(" token="); sb.append(token); sb.append('}');
8312 stringName = sb.toString();
8313 }
8314 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008315 }
8316 };
8317
8318 class AppWindowToken extends WindowToken {
8319 // Non-null only for application tokens.
8320 final IApplicationToken appToken;
8321
8322 // All of the windows and child windows that are included in this
8323 // application token. Note this list is NOT sorted!
8324 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8325
8326 int groupId = -1;
8327 boolean appFullscreen;
8328 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008329
8330 // The input dispatching timeout for this application token in nanoseconds.
8331 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008333 // These are used for determining when all windows associated with
8334 // an activity have been drawn, so they can be made visible together
8335 // at the same time.
8336 int lastTransactionSequence = mTransactionSequence-1;
8337 int numInterestingWindows;
8338 int numDrawnWindows;
8339 boolean inPendingTransaction;
8340 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008342 // Is this token going to be hidden in a little while? If so, it
8343 // won't be taken into account for setting the screen orientation.
8344 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 // Is this window's surface needed? This is almost like hidden, except
8347 // it will sometimes be true a little earlier: when the token has
8348 // been shown, but is still waiting for its app transition to execute
8349 // before making its windows shown.
8350 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352 // Have we told the window clients to hide themselves?
8353 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 // Last visibility state we reported to the app token.
8356 boolean reportedVisible;
8357
8358 // Set to true when the token has been removed from the window mgr.
8359 boolean removed;
8360
8361 // Have we been asked to have this token keep the screen frozen?
8362 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008364 boolean animating;
8365 Animation animation;
8366 boolean hasTransformation;
8367 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008369 // Offset to the window of all layers in the token, for use by
8370 // AppWindowToken animations.
8371 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008373 // Information about an application starting window if displayed.
8374 StartingData startingData;
8375 WindowState startingWindow;
8376 View startingView;
8377 boolean startingDisplayed;
8378 boolean startingMoved;
8379 boolean firstWindowDrawn;
8380
Jeff Brown928e0542011-01-10 11:17:36 -08008381 // Input application handle used by the input dispatcher.
8382 InputApplicationHandle mInputApplicationHandle;
8383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008384 AppWindowToken(IApplicationToken _token) {
8385 super(_token.asBinder(),
8386 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8387 appWindowToken = this;
8388 appToken = _token;
Jeff Brown928e0542011-01-10 11:17:36 -08008389 mInputApplicationHandle = new InputApplicationHandle(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008390 }
Romain Guy06882f82009-06-10 13:36:04 -07008391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008392 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008393 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008394 TAG, "Setting animation in " + this + ": " + anim);
8395 animation = anim;
8396 animating = false;
8397 anim.restrictDuration(MAX_ANIMATION_DURATION);
8398 anim.scaleCurrentDuration(mTransitionAnimationScale);
8399 int zorder = anim.getZAdjustment();
8400 int adj = 0;
8401 if (zorder == Animation.ZORDER_TOP) {
8402 adj = TYPE_LAYER_OFFSET;
8403 } else if (zorder == Animation.ZORDER_BOTTOM) {
8404 adj = -TYPE_LAYER_OFFSET;
8405 }
Romain Guy06882f82009-06-10 13:36:04 -07008406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 if (animLayerAdjustment != adj) {
8408 animLayerAdjustment = adj;
8409 updateLayers();
8410 }
8411 }
Romain Guy06882f82009-06-10 13:36:04 -07008412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008413 public void setDummyAnimation() {
8414 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008415 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008416 TAG, "Setting dummy animation in " + this);
8417 animation = sDummyAnimation;
8418 }
8419 }
8420
8421 public void clearAnimation() {
8422 if (animation != null) {
8423 animation = null;
8424 animating = true;
8425 }
8426 }
Romain Guy06882f82009-06-10 13:36:04 -07008427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008428 void updateLayers() {
8429 final int N = allAppWindows.size();
8430 final int adj = animLayerAdjustment;
8431 for (int i=0; i<N; i++) {
8432 WindowState w = allAppWindows.get(i);
8433 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008434 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008435 + w.mAnimLayer);
8436 if (w == mInputMethodTarget) {
8437 setInputMethodAnimLayerAdjustment(adj);
8438 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008439 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008440 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008442 }
8443 }
Romain Guy06882f82009-06-10 13:36:04 -07008444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008445 void sendAppVisibilityToClients() {
8446 final int N = allAppWindows.size();
8447 for (int i=0; i<N; i++) {
8448 WindowState win = allAppWindows.get(i);
8449 if (win == startingWindow && clientHidden) {
8450 // Don't hide the starting window.
8451 continue;
8452 }
8453 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008454 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 "Setting visibility of " + win + ": " + (!clientHidden));
8456 win.mClient.dispatchAppVisibility(!clientHidden);
8457 } catch (RemoteException e) {
8458 }
8459 }
8460 }
Romain Guy06882f82009-06-10 13:36:04 -07008461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008462 void showAllWindowsLocked() {
8463 final int NW = allAppWindows.size();
8464 for (int i=0; i<NW; i++) {
8465 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008466 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467 "performing show on: " + w);
8468 w.performShowLocked();
8469 }
8470 }
Romain Guy06882f82009-06-10 13:36:04 -07008471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008472 // This must be called while inside a transaction.
8473 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008474 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008475 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008477 if (animation == sDummyAnimation) {
8478 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008479 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008480 // when it is really time to animate, this will be set to
8481 // a real animation and the next call will execute normally.
8482 return false;
8483 }
Romain Guy06882f82009-06-10 13:36:04 -07008484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8486 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008487 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488 TAG, "Starting animation in " + this +
8489 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8490 + " scale=" + mTransitionAnimationScale
8491 + " allDrawn=" + allDrawn + " animating=" + animating);
8492 animation.initialize(dw, dh, dw, dh);
8493 animation.setStartTime(currentTime);
8494 animating = true;
8495 }
8496 transformation.clear();
8497 final boolean more = animation.getTransformation(
8498 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008499 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 TAG, "Stepped animation in " + this +
8501 ": more=" + more + ", xform=" + transformation);
8502 if (more) {
8503 // we're done!
8504 hasTransformation = true;
8505 return true;
8506 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008507 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 TAG, "Finished animation in " + this +
8509 " @ " + currentTime);
8510 animation = null;
8511 }
8512 } else if (animation != null) {
8513 // If the display is frozen, and there is a pending animation,
8514 // clear it and make sure we run the cleanup code.
8515 animating = true;
8516 animation = null;
8517 }
8518
8519 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 if (!animating) {
8522 return false;
8523 }
8524
8525 clearAnimation();
8526 animating = false;
8527 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8528 moveInputMethodWindowsIfNeededLocked(true);
8529 }
Romain Guy06882f82009-06-10 13:36:04 -07008530
Joe Onorato8a9b2202010-02-26 18:56:32 -08008531 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 TAG, "Animation done in " + this
8533 + ": reportedVisible=" + reportedVisible);
8534
8535 transformation.clear();
8536 if (animLayerAdjustment != 0) {
8537 animLayerAdjustment = 0;
8538 updateLayers();
8539 }
Romain Guy06882f82009-06-10 13:36:04 -07008540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 final int N = windows.size();
8542 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008543 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008544 }
8545 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008547 return false;
8548 }
8549
8550 void updateReportedVisibilityLocked() {
8551 if (appToken == null) {
8552 return;
8553 }
Romain Guy06882f82009-06-10 13:36:04 -07008554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 int numInteresting = 0;
8556 int numVisible = 0;
8557 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008558
Joe Onorato8a9b2202010-02-26 18:56:32 -08008559 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008560 final int N = allAppWindows.size();
8561 for (int i=0; i<N; i++) {
8562 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008563 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008564 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008565 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8566 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008567 continue;
8568 }
8569 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008570 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008571 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008573 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008574 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 + " pv=" + win.mPolicyVisibility
8576 + " dp=" + win.mDrawPending
8577 + " cdp=" + win.mCommitDrawPending
8578 + " ah=" + win.mAttachedHidden
8579 + " th="
8580 + (win.mAppToken != null
8581 ? win.mAppToken.hiddenRequested : false)
8582 + " a=" + win.mAnimating);
8583 }
8584 }
8585 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008586 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 if (!win.isAnimating()) {
8588 numVisible++;
8589 }
8590 nowGone = false;
8591 } else if (win.isAnimating()) {
8592 nowGone = false;
8593 }
8594 }
Romain Guy06882f82009-06-10 13:36:04 -07008595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008596 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008597 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598 + numInteresting + " visible=" + numVisible);
8599 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008600 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 TAG, "Visibility changed in " + this
8602 + ": vis=" + nowVisible);
8603 reportedVisible = nowVisible;
8604 Message m = mH.obtainMessage(
8605 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8606 nowVisible ? 1 : 0,
8607 nowGone ? 1 : 0,
8608 this);
8609 mH.sendMessage(m);
8610 }
8611 }
Romain Guy06882f82009-06-10 13:36:04 -07008612
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008613 WindowState findMainWindow() {
8614 int j = windows.size();
8615 while (j > 0) {
8616 j--;
8617 WindowState win = windows.get(j);
8618 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8619 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8620 return win;
8621 }
8622 }
8623 return null;
8624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 void dump(PrintWriter pw, String prefix) {
8627 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008628 if (appToken != null) {
8629 pw.print(prefix); pw.println("app=true");
8630 }
8631 if (allAppWindows.size() > 0) {
8632 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8633 }
8634 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008635 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008636 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8637 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8638 pw.print(" clientHidden="); pw.print(clientHidden);
8639 pw.print(" willBeHidden="); pw.print(willBeHidden);
8640 pw.print(" reportedVisible="); pw.println(reportedVisible);
8641 if (paused || freezingScreen) {
8642 pw.print(prefix); pw.print("paused="); pw.print(paused);
8643 pw.print(" freezingScreen="); pw.println(freezingScreen);
8644 }
8645 if (numInterestingWindows != 0 || numDrawnWindows != 0
8646 || inPendingTransaction || allDrawn) {
8647 pw.print(prefix); pw.print("numInterestingWindows=");
8648 pw.print(numInterestingWindows);
8649 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8650 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8651 pw.print(" allDrawn="); pw.println(allDrawn);
8652 }
8653 if (animating || animation != null) {
8654 pw.print(prefix); pw.print("animating="); pw.print(animating);
8655 pw.print(" animation="); pw.println(animation);
8656 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008657 if (hasTransformation) {
8658 pw.print(prefix); pw.print("XForm: ");
8659 transformation.printShortString(pw);
8660 pw.println();
8661 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008662 if (animLayerAdjustment != 0) {
8663 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8664 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008665 if (startingData != null || removed || firstWindowDrawn) {
8666 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8667 pw.print(" removed="); pw.print(removed);
8668 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8669 }
8670 if (startingWindow != null || startingView != null
8671 || startingDisplayed || startingMoved) {
8672 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8673 pw.print(" startingView="); pw.print(startingView);
8674 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8675 pw.print(" startingMoved"); pw.println(startingMoved);
8676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008677 }
8678
8679 @Override
8680 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008681 if (stringName == null) {
8682 StringBuilder sb = new StringBuilder();
8683 sb.append("AppWindowToken{");
8684 sb.append(Integer.toHexString(System.identityHashCode(this)));
8685 sb.append(" token="); sb.append(token); sb.append('}');
8686 stringName = sb.toString();
8687 }
8688 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 }
8690 }
Romain Guy06882f82009-06-10 13:36:04 -07008691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008692 // -------------------------------------------------------------
8693 // DummyAnimation
8694 // -------------------------------------------------------------
8695
8696 // This is an animation that does nothing: it just immediately finishes
8697 // itself every time it is called. It is used as a stub animation in cases
8698 // where we want to synchronize multiple things that may be animating.
8699 static final class DummyAnimation extends Animation {
8700 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8701 return false;
8702 }
8703 }
8704 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 // -------------------------------------------------------------
8707 // Async Handler
8708 // -------------------------------------------------------------
8709
8710 static final class StartingData {
8711 final String pkg;
8712 final int theme;
8713 final CharSequence nonLocalizedLabel;
8714 final int labelRes;
8715 final int icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008716 final int windowFlags;
Romain Guy06882f82009-06-10 13:36:04 -07008717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008718 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008719 int _labelRes, int _icon, int _windowFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008720 pkg = _pkg;
8721 theme = _theme;
8722 nonLocalizedLabel = _nonLocalizedLabel;
8723 labelRes = _labelRes;
8724 icon = _icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008725 windowFlags = _windowFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008726 }
8727 }
8728
8729 private final class H extends Handler {
8730 public static final int REPORT_FOCUS_CHANGE = 2;
8731 public static final int REPORT_LOSING_FOCUS = 3;
8732 public static final int ANIMATE = 4;
8733 public static final int ADD_STARTING = 5;
8734 public static final int REMOVE_STARTING = 6;
8735 public static final int FINISHED_STARTING = 7;
8736 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008737 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8738 public static final int HOLD_SCREEN_CHANGED = 12;
8739 public static final int APP_TRANSITION_TIMEOUT = 13;
8740 public static final int PERSIST_ANIMATION_SCALE = 14;
8741 public static final int FORCE_GC = 15;
8742 public static final int ENABLE_SCREEN = 16;
8743 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008744 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008745 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008746 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008747 public static final int DRAG_END_TIMEOUT = 21;
Romain Guy06882f82009-06-10 13:36:04 -07008748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008749 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008751 public H() {
8752 }
Romain Guy06882f82009-06-10 13:36:04 -07008753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008754 @Override
8755 public void handleMessage(Message msg) {
8756 switch (msg.what) {
8757 case REPORT_FOCUS_CHANGE: {
8758 WindowState lastFocus;
8759 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 synchronized(mWindowMap) {
8762 lastFocus = mLastFocus;
8763 newFocus = mCurrentFocus;
8764 if (lastFocus == newFocus) {
8765 // Focus is not changing, so nothing to do.
8766 return;
8767 }
8768 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008769 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008770 // + " to " + newFocus);
8771 if (newFocus != null && lastFocus != null
8772 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008773 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008774 mLosingFocus.add(lastFocus);
8775 lastFocus = null;
8776 }
8777 }
8778
8779 if (lastFocus != newFocus) {
8780 //System.out.println("Changing focus from " + lastFocus
8781 // + " to " + newFocus);
8782 if (newFocus != null) {
8783 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008784 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008785 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8786 } catch (RemoteException e) {
8787 // Ignore if process has died.
8788 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008789 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 }
8791
8792 if (lastFocus != null) {
8793 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008794 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8796 } catch (RemoteException e) {
8797 // Ignore if process has died.
8798 }
8799 }
8800 }
8801 } break;
8802
8803 case REPORT_LOSING_FOCUS: {
8804 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008806 synchronized(mWindowMap) {
8807 losers = mLosingFocus;
8808 mLosingFocus = new ArrayList<WindowState>();
8809 }
8810
8811 final int N = losers.size();
8812 for (int i=0; i<N; i++) {
8813 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008814 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8816 } catch (RemoteException e) {
8817 // Ignore if process has died.
8818 }
8819 }
8820 } break;
8821
8822 case ANIMATE: {
8823 synchronized(mWindowMap) {
8824 mAnimationPending = false;
8825 performLayoutAndPlaceSurfacesLocked();
8826 }
8827 } break;
8828
8829 case ADD_STARTING: {
8830 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8831 final StartingData sd = wtoken.startingData;
8832
8833 if (sd == null) {
8834 // Animation has been canceled... do nothing.
8835 return;
8836 }
Romain Guy06882f82009-06-10 13:36:04 -07008837
Joe Onorato8a9b2202010-02-26 18:56:32 -08008838 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008839 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 View view = null;
8842 try {
8843 view = mPolicy.addStartingWindow(
8844 wtoken.token, sd.pkg,
8845 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008846 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008847 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008848 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008849 }
8850
8851 if (view != null) {
8852 boolean abort = false;
8853
8854 synchronized(mWindowMap) {
8855 if (wtoken.removed || wtoken.startingData == null) {
8856 // If the window was successfully added, then
8857 // we need to remove it.
8858 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008859 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008860 "Aborted starting " + wtoken
8861 + ": removed=" + wtoken.removed
8862 + " startingData=" + wtoken.startingData);
8863 wtoken.startingWindow = null;
8864 wtoken.startingData = null;
8865 abort = true;
8866 }
8867 } else {
8868 wtoken.startingView = view;
8869 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008870 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 "Added starting " + wtoken
8872 + ": startingWindow="
8873 + wtoken.startingWindow + " startingView="
8874 + wtoken.startingView);
8875 }
8876
8877 if (abort) {
8878 try {
8879 mPolicy.removeStartingWindow(wtoken.token, view);
8880 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008881 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 }
8883 }
8884 }
8885 } break;
8886
8887 case REMOVE_STARTING: {
8888 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8889 IBinder token = null;
8890 View view = null;
8891 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008892 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008893 + wtoken + ": startingWindow="
8894 + wtoken.startingWindow + " startingView="
8895 + wtoken.startingView);
8896 if (wtoken.startingWindow != null) {
8897 view = wtoken.startingView;
8898 token = wtoken.token;
8899 wtoken.startingData = null;
8900 wtoken.startingView = null;
8901 wtoken.startingWindow = null;
8902 }
8903 }
8904 if (view != null) {
8905 try {
8906 mPolicy.removeStartingWindow(token, view);
8907 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008908 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008909 }
8910 }
8911 } break;
8912
8913 case FINISHED_STARTING: {
8914 IBinder token = null;
8915 View view = null;
8916 while (true) {
8917 synchronized (mWindowMap) {
8918 final int N = mFinishedStarting.size();
8919 if (N <= 0) {
8920 break;
8921 }
8922 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8923
Joe Onorato8a9b2202010-02-26 18:56:32 -08008924 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008925 "Finished starting " + wtoken
8926 + ": startingWindow=" + wtoken.startingWindow
8927 + " startingView=" + wtoken.startingView);
8928
8929 if (wtoken.startingWindow == null) {
8930 continue;
8931 }
8932
8933 view = wtoken.startingView;
8934 token = wtoken.token;
8935 wtoken.startingData = null;
8936 wtoken.startingView = null;
8937 wtoken.startingWindow = null;
8938 }
8939
8940 try {
8941 mPolicy.removeStartingWindow(token, view);
8942 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008943 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008944 }
8945 }
8946 } break;
8947
8948 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8949 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8950
8951 boolean nowVisible = msg.arg1 != 0;
8952 boolean nowGone = msg.arg2 != 0;
8953
8954 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008955 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008956 TAG, "Reporting visible in " + wtoken
8957 + " visible=" + nowVisible
8958 + " gone=" + nowGone);
8959 if (nowVisible) {
8960 wtoken.appToken.windowsVisible();
8961 } else {
8962 wtoken.appToken.windowsGone();
8963 }
8964 } catch (RemoteException ex) {
8965 }
8966 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008968 case WINDOW_FREEZE_TIMEOUT: {
8969 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008970 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008971 int i = mWindows.size();
8972 while (i > 0) {
8973 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008974 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008975 if (w.mOrientationChanging) {
8976 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008977 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008978 }
8979 }
8980 performLayoutAndPlaceSurfacesLocked();
8981 }
8982 break;
8983 }
Romain Guy06882f82009-06-10 13:36:04 -07008984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 case HOLD_SCREEN_CHANGED: {
8986 Session oldHold;
8987 Session newHold;
8988 synchronized (mWindowMap) {
8989 oldHold = mLastReportedHold;
8990 newHold = (Session)msg.obj;
8991 mLastReportedHold = newHold;
8992 }
Romain Guy06882f82009-06-10 13:36:04 -07008993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008994 if (oldHold != newHold) {
8995 try {
8996 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008997 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 "window",
8999 BatteryStats.WAKE_TYPE_WINDOW);
9000 }
9001 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009002 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009003 "window",
9004 BatteryStats.WAKE_TYPE_WINDOW);
9005 }
9006 } catch (RemoteException e) {
9007 }
9008 }
9009 break;
9010 }
Romain Guy06882f82009-06-10 13:36:04 -07009011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009012 case APP_TRANSITION_TIMEOUT: {
9013 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009014 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009015 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 "*** APP TRANSITION TIMEOUT");
9017 mAppTransitionReady = true;
9018 mAppTransitionTimeout = true;
9019 performLayoutAndPlaceSurfacesLocked();
9020 }
9021 }
9022 break;
9023 }
Romain Guy06882f82009-06-10 13:36:04 -07009024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009025 case PERSIST_ANIMATION_SCALE: {
9026 Settings.System.putFloat(mContext.getContentResolver(),
9027 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9028 Settings.System.putFloat(mContext.getContentResolver(),
9029 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9030 break;
9031 }
Romain Guy06882f82009-06-10 13:36:04 -07009032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009033 case FORCE_GC: {
9034 synchronized(mWindowMap) {
9035 if (mAnimationPending) {
9036 // If we are animating, don't do the gc now but
9037 // delay a bit so we don't interrupt the animation.
9038 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9039 2000);
9040 return;
9041 }
9042 // If we are currently rotating the display, it will
9043 // schedule a new message when done.
9044 if (mDisplayFrozen) {
9045 return;
9046 }
9047 mFreezeGcPending = 0;
9048 }
9049 Runtime.getRuntime().gc();
9050 break;
9051 }
Romain Guy06882f82009-06-10 13:36:04 -07009052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009053 case ENABLE_SCREEN: {
9054 performEnableScreen();
9055 break;
9056 }
Romain Guy06882f82009-06-10 13:36:04 -07009057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009058 case APP_FREEZE_TIMEOUT: {
9059 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009060 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 int i = mAppTokens.size();
9062 while (i > 0) {
9063 i--;
9064 AppWindowToken tok = mAppTokens.get(i);
9065 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009066 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 unsetAppFreezingScreenLocked(tok, true, true);
9068 }
9069 }
9070 }
9071 break;
9072 }
Romain Guy06882f82009-06-10 13:36:04 -07009073
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009074 case SEND_NEW_CONFIGURATION: {
9075 removeMessages(SEND_NEW_CONFIGURATION);
9076 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009077 break;
9078 }
Romain Guy06882f82009-06-10 13:36:04 -07009079
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009080 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009081 if (mWindowsChanged) {
9082 synchronized (mWindowMap) {
9083 mWindowsChanged = false;
9084 }
9085 notifyWindowsChanged();
9086 }
9087 break;
9088 }
9089
Christopher Tatea53146c2010-09-07 11:57:52 -07009090 case DRAG_START_TIMEOUT: {
9091 IBinder win = (IBinder)msg.obj;
9092 if (DEBUG_DRAG) {
9093 Slog.w(TAG, "Timeout starting drag by win " + win);
9094 }
9095 synchronized (mWindowMap) {
9096 // !!! TODO: ANR the app that has failed to start the drag in time
9097 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07009098 mDragState.unregister();
9099 mInputMonitor.updateInputWindowsLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07009100 mDragState.reset();
9101 mDragState = null;
9102 }
9103 }
Chris Tated4533f142010-10-19 15:15:08 -07009104 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07009105 }
9106
Chris Tated4533f142010-10-19 15:15:08 -07009107 case DRAG_END_TIMEOUT: {
9108 IBinder win = (IBinder)msg.obj;
9109 if (DEBUG_DRAG) {
9110 Slog.w(TAG, "Timeout ending drag to win " + win);
9111 }
9112 synchronized (mWindowMap) {
9113 // !!! TODO: ANR the drag-receiving app
9114 mDragState.mDragResult = false;
9115 mDragState.endDragLw();
9116 }
9117 break;
9118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009119 }
9120 }
9121 }
9122
9123 // -------------------------------------------------------------
9124 // IWindowManager API
9125 // -------------------------------------------------------------
9126
9127 public IWindowSession openSession(IInputMethodClient client,
9128 IInputContext inputContext) {
9129 if (client == null) throw new IllegalArgumentException("null client");
9130 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009131 Session session = new Session(client, inputContext);
9132 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009133 }
9134
9135 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9136 synchronized (mWindowMap) {
9137 // The focus for the client is the window immediately below
9138 // where we would place the input method window.
9139 int idx = findDesiredInputMethodWindowIndexLocked(false);
9140 WindowState imFocus;
9141 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07009142 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009143 if (imFocus != null) {
9144 if (imFocus.mSession.mClient != null &&
9145 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9146 return true;
9147 }
9148 }
9149 }
9150 }
9151 return false;
9152 }
Romain Guy06882f82009-06-10 13:36:04 -07009153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 // -------------------------------------------------------------
9155 // Internals
9156 // -------------------------------------------------------------
9157
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009158 final WindowState windowForClientLocked(Session session, IWindow client,
9159 boolean throwOnError) {
9160 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 }
Romain Guy06882f82009-06-10 13:36:04 -07009162
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009163 final WindowState windowForClientLocked(Session session, IBinder client,
9164 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009166 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009167 TAG, "Looking up client " + client + ": " + win);
9168 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009169 RuntimeException ex = new IllegalArgumentException(
9170 "Requested window " + client + " does not exist");
9171 if (throwOnError) {
9172 throw ex;
9173 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009174 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009175 return null;
9176 }
9177 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009178 RuntimeException ex = new IllegalArgumentException(
9179 "Requested window " + client + " is in session " +
9180 win.mSession + ", not " + session);
9181 if (throwOnError) {
9182 throw ex;
9183 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009184 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009185 return null;
9186 }
9187
9188 return win;
9189 }
9190
Dianne Hackborna8f60182009-09-01 19:01:50 -07009191 final void rebuildAppWindowListLocked() {
9192 int NW = mWindows.size();
9193 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009194 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009195 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009196
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009197 if (mRebuildTmp.length < NW) {
9198 mRebuildTmp = new WindowState[NW+10];
9199 }
9200
Dianne Hackborna8f60182009-09-01 19:01:50 -07009201 // First remove all existing app windows.
9202 i=0;
9203 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07009204 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009205 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07009206 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009207 win.mRebuilding = true;
9208 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009209 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009210 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009211 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009212 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009213 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009214 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009215 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9216 && lastWallpaper == i-1) {
9217 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009218 }
9219 i++;
9220 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009221
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009222 // The wallpaper window(s) typically live at the bottom of the stack,
9223 // so skip them before adding app tokens.
9224 lastWallpaper++;
9225 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009226
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009227 // First add all of the exiting app tokens... these are no longer
9228 // in the main app list, but still have windows shown. We put them
9229 // in the back because now that the animation is over we no longer
9230 // will care about them.
9231 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009232 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009233 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9234 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009235
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009236 // And add in the still active app tokens in Z order.
9237 NT = mAppTokens.size();
9238 for (int j=0; j<NT; j++) {
9239 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009240 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009241
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009242 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009243 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009244 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009245 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009246 for (i=0; i<numRemoved; i++) {
9247 WindowState ws = mRebuildTmp[i];
9248 if (ws.mRebuilding) {
9249 StringWriter sw = new StringWriter();
9250 PrintWriter pw = new PrintWriter(sw);
9251 ws.dump(pw, "");
9252 pw.flush();
9253 Slog.w(TAG, "This window was lost: " + ws);
9254 Slog.w(TAG, sw.toString());
9255 }
9256 }
9257 Slog.w(TAG, "Current app token list:");
9258 dumpAppTokensLocked();
9259 Slog.w(TAG, "Final window list:");
9260 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009261 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009262 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009264 private final void assignLayersLocked() {
9265 int N = mWindows.size();
9266 int curBaseLayer = 0;
9267 int curLayer = 0;
9268 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009269
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009270 if (DEBUG_LAYERS) {
9271 RuntimeException here = new RuntimeException("here");
9272 here.fillInStackTrace();
9273 Log.v(TAG, "Assigning layers", here);
9274 }
9275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009276 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07009277 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009278 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9279 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 curLayer += WINDOW_LAYER_MULTIPLIER;
9281 w.mLayer = curLayer;
9282 } else {
9283 curBaseLayer = curLayer = w.mBaseLayer;
9284 w.mLayer = curLayer;
9285 }
9286 if (w.mTargetAppToken != null) {
9287 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9288 } else if (w.mAppToken != null) {
9289 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9290 } else {
9291 w.mAnimLayer = w.mLayer;
9292 }
9293 if (w.mIsImWindow) {
9294 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009295 } else if (w.mIsWallpaper) {
9296 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009298 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299 + w.mAnimLayer);
9300 //System.out.println(
9301 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9302 }
9303 }
9304
9305 private boolean mInLayout = false;
9306 private final void performLayoutAndPlaceSurfacesLocked() {
9307 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009308 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 throw new RuntimeException("Recursive call!");
9310 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009311 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009312 return;
9313 }
9314
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009315 if (mWaitingForConfig) {
9316 // Our configuration has changed (most likely rotation), but we
9317 // don't yet have the complete configuration to report to
9318 // applications. Don't do any window layout until we have it.
9319 return;
9320 }
9321
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009322 if (mDisplay == null) {
9323 // Not yet initialized, nothing to do.
9324 return;
9325 }
9326
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009327 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009329
9330 try {
9331 if (mForceRemoves != null) {
9332 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009333 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009334 for (int i=0; i<mForceRemoves.size(); i++) {
9335 WindowState ws = mForceRemoves.get(i);
9336 Slog.i(TAG, "Force removing: " + ws);
9337 removeWindowInnerLocked(ws.mSession, ws);
9338 }
9339 mForceRemoves = null;
9340 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
9341 Object tmp = new Object();
9342 synchronized (tmp) {
9343 try {
9344 tmp.wait(250);
9345 } catch (InterruptedException e) {
9346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 }
9348 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009349 } catch (RuntimeException e) {
9350 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009353 try {
9354 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009355
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009356 int N = mPendingRemove.size();
9357 if (N > 0) {
9358 if (mPendingRemoveTmp.length < N) {
9359 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009360 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009361 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009363 for (int i=0; i<N; i++) {
9364 WindowState w = mPendingRemoveTmp[i];
9365 removeWindowInnerLocked(w.mSession, w);
9366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367
9368 mInLayout = false;
9369 assignLayersLocked();
9370 mLayoutNeeded = true;
9371 performLayoutAndPlaceSurfacesLocked();
9372
9373 } else {
9374 mInLayout = false;
9375 if (mLayoutNeeded) {
9376 requestAnimationLocked(0);
9377 }
9378 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009379 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009380 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9381 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009383 } catch (RuntimeException e) {
9384 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009385 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009386 }
9387 }
9388
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009389 private final int performLayoutLockedInner(boolean initial) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009390 if (!mLayoutNeeded) {
9391 return 0;
9392 }
9393
9394 mLayoutNeeded = false;
9395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 final int dw = mDisplay.getWidth();
9397 final int dh = mDisplay.getHeight();
9398
9399 final int N = mWindows.size();
9400 int i;
9401
Joe Onorato8a9b2202010-02-26 18:56:32 -08009402 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009403 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9404
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009405 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009406
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009407 int seq = mLayoutSeq+1;
9408 if (seq < 0) seq = 0;
9409 mLayoutSeq = seq;
9410
9411 // First perform layout of any root windows (not attached
9412 // to another window).
9413 int topAttached = -1;
9414 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009415 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009416
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009417 // Don't do layout of a window if it is not visible, or
9418 // soon won't be visible, to avoid wasting time and funky
9419 // changes while a window is animating away.
9420 final AppWindowToken atoken = win.mAppToken;
9421 final boolean gone = win.mViewVisibility == View.GONE
9422 || !win.mRelayoutCalled
9423 || win.mRootToken.hidden
9424 || (atoken != null && atoken.hiddenRequested)
9425 || win.mAttachedHidden
9426 || win.mExiting || win.mDestroying;
9427
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009428 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
9429 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009430 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9431 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009432 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009433 + win.mViewVisibility + " mRelayoutCalled="
9434 + win.mRelayoutCalled + " hidden="
9435 + win.mRootToken.hidden + " hiddenRequested="
9436 + (atoken != null && atoken.hiddenRequested)
9437 + " mAttachedHidden=" + win.mAttachedHidden);
9438 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009439
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009440 // If this view is GONE, then skip it -- keep the current
9441 // frame, and let the caller know so they can ignore it
9442 // if they want. (We do the normal layout for INVISIBLE
9443 // windows, since that means "perform layout as normal,
9444 // just don't display").
9445 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009446 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009447 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009448 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009449 win.mContentChanged = false;
9450 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009451 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9452 win.mLayoutSeq = seq;
9453 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9454 + win.mFrame + " mContainingFrame="
9455 + win.mContainingFrame + " mDisplayFrame="
9456 + win.mDisplayFrame);
9457 } else {
9458 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009459 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009461 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009462
9463 // Now perform layout of attached windows, which usually
9464 // depend on the position of the window they are attached to.
9465 // XXX does not deal with windows that are attached to windows
9466 // that are themselves attached.
9467 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009468 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009469
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009470 if (win.mLayoutAttached) {
9471 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9472 + " mHaveFrame=" + win.mHaveFrame
9473 + " mViewVisibility=" + win.mViewVisibility
9474 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009475 // If this view is GONE, then skip it -- keep the current
9476 // frame, and let the caller know so they can ignore it
9477 // if they want. (We do the normal layout for INVISIBLE
9478 // windows, since that means "perform layout as normal,
9479 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009480 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9481 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009482 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009483 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009484 win.mContentChanged = false;
9485 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009486 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9487 win.mLayoutSeq = seq;
9488 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9489 + win.mFrame + " mContainingFrame="
9490 + win.mContainingFrame + " mDisplayFrame="
9491 + win.mDisplayFrame);
9492 }
9493 }
9494 }
Jeff Brown349703e2010-06-22 01:27:15 -07009495
9496 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009497 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009498
9499 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 }
Romain Guy06882f82009-06-10 13:36:04 -07009501
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009502 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 private final void performLayoutAndPlaceSurfacesLockedInner(
9504 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009505 if (mDisplay == null) {
9506 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9507 return;
9508 }
9509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 final long currentTime = SystemClock.uptimeMillis();
9511 final int dw = mDisplay.getWidth();
9512 final int dh = mDisplay.getHeight();
9513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 int i;
9515
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009516 if (mFocusMayChange) {
9517 mFocusMayChange = false;
9518 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9519 }
9520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009521 // Initialize state of exiting tokens.
9522 for (i=mExitingTokens.size()-1; i>=0; i--) {
9523 mExitingTokens.get(i).hasVisible = false;
9524 }
9525
9526 // Initialize state of exiting applications.
9527 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9528 mExitingAppTokens.get(i).hasVisible = false;
9529 }
9530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 boolean orientationChangeComplete = true;
9532 Session holdScreen = null;
9533 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009534 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 boolean focusDisplayed = false;
9536 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009537 boolean createWatermark = false;
9538
9539 if (mFxSession == null) {
9540 mFxSession = new SurfaceSession();
9541 createWatermark = true;
9542 }
9543
9544 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009545
9546 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009547
9548 if (createWatermark) {
9549 createWatermark();
9550 }
9551 if (mWatermark != null) {
9552 mWatermark.positionSurface(dw, dh);
9553 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009554 if (mStrictModeFlash != null) {
9555 mStrictModeFlash.positionSurface(dw, dh);
9556 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009558 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009559 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009560 int repeats = 0;
9561 int changes = 0;
9562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009564 repeats++;
9565 if (repeats > 6) {
9566 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9567 mLayoutNeeded = false;
9568 break;
9569 }
9570
9571 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9572 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9573 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9574 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9575 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9576 assignLayersLocked();
9577 mLayoutNeeded = true;
9578 }
9579 }
9580 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9581 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9582 if (updateOrientationFromAppTokensLocked()) {
9583 mLayoutNeeded = true;
9584 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9585 }
9586 }
9587 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9588 mLayoutNeeded = true;
9589 }
9590 }
9591
9592 // FIRST LOOP: Perform a layout, if needed.
9593 if (repeats < 4) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009594 changes = performLayoutLockedInner(repeats == 0);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009595 if (changes != 0) {
9596 continue;
9597 }
9598 } else {
9599 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9600 changes = 0;
9601 }
9602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009603 final int transactionSequence = ++mTransactionSequence;
9604
9605 // Update animations of all applications, including those
9606 // associated with exiting/removed apps
9607 boolean tokensAnimating = false;
9608 final int NAT = mAppTokens.size();
9609 for (i=0; i<NAT; i++) {
9610 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9611 tokensAnimating = true;
9612 }
9613 }
9614 final int NEAT = mExitingAppTokens.size();
9615 for (i=0; i<NEAT; i++) {
9616 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9617 tokensAnimating = true;
9618 }
9619 }
9620
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009621 // SECOND LOOP: Execute animations and update visibility of windows.
9622
Joe Onorato8a9b2202010-02-26 18:56:32 -08009623 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009624 + transactionSequence + " tokensAnimating="
9625 + tokensAnimating);
9626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009627 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009628
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009629 if (mScreenRotationAnimation != null) {
9630 if (mScreenRotationAnimation.isAnimating()) {
9631 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
9632 animating = true;
9633 } else {
9634 mScreenRotationAnimation = null;
9635 }
9636 }
9637 }
9638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009639 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009640 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009641 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009642 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643
9644 mPolicy.beginAnimationLw(dw, dh);
9645
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009646 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009648 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009649 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650
9651 final WindowManager.LayoutParams attrs = w.mAttrs;
9652
9653 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009654 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009655 if (w.commitFinishDrawingLocked(currentTime)) {
9656 if ((w.mAttrs.flags
9657 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009658 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009659 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009660 wallpaperMayChange = true;
9661 }
9662 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009663
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009664 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009665
9666 int animDw = dw;
9667 int animDh = dh;
9668
9669 // If the window has moved due to its containing
9670 // content frame changing, then we'd like to animate
9671 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08009672 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009673 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009674 // Frame has moved, containing content frame
9675 // has also moved, and we're not currently animating...
9676 // let's do something.
9677 Animation a = AnimationUtils.loadAnimation(mContext,
9678 com.android.internal.R.anim.window_move_from_decor);
9679 w.setAnimation(a);
9680 animDw = w.mLastFrame.left - w.mFrame.left;
9681 animDh = w.mLastFrame.top - w.mFrame.top;
9682 }
9683
9684 // Execute animation.
9685 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
9686 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009687
9688 // If this window is animating, make a note that we have
9689 // an animating window and take care of a request to run
9690 // a detached wallpaper animation.
9691 if (nowAnimating) {
9692 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
9693 windowDetachedWallpaper = w;
9694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009696 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009697
9698 // If this window's app token is running a detached wallpaper
9699 // animation, make a note so we can ensure the wallpaper is
9700 // displayed behind it.
9701 if (w.mAppToken != null && w.mAppToken.animation != null
9702 && w.mAppToken.animation.getDetachWallpaper()) {
9703 windowDetachedWallpaper = w;
9704 }
9705
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009706 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9707 wallpaperMayChange = true;
9708 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009709
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009710 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009711 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009712 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009713 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009714 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009715 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009716 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009717 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9718 forceHiding = true;
9719 }
9720 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9721 boolean changed;
9722 if (forceHiding) {
9723 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009724 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9725 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009726 } else {
9727 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009728 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9729 "Now policy shown: " + w);
9730 if (changed) {
9731 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009732 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009733 // Assume we will need to animate. If
9734 // we don't (because the wallpaper will
9735 // stay with the lock screen), then we will
9736 // clean up later.
9737 Animation a = mPolicy.createForceHideEnterAnimation();
9738 if (a != null) {
9739 w.setAnimation(a);
9740 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009741 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009742 if (mCurrentFocus == null ||
9743 mCurrentFocus.mLayer < w.mLayer) {
9744 // We are showing on to of the current
9745 // focus, so re-evaluate focus to make
9746 // sure it is correct.
9747 mFocusMayChange = true;
9748 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009749 }
9750 }
9751 if (changed && (attrs.flags
9752 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9753 wallpaperMayChange = true;
9754 }
9755 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 mPolicy.animatingWindowLw(w, attrs);
9758 }
9759
9760 final AppWindowToken atoken = w.mAppToken;
9761 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9762 if (atoken.lastTransactionSequence != transactionSequence) {
9763 atoken.lastTransactionSequence = transactionSequence;
9764 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9765 atoken.startingDisplayed = false;
9766 }
9767 if ((w.isOnScreen() || w.mAttrs.type
9768 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9769 && !w.mExiting && !w.mDestroying) {
9770 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009771 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009772 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009773 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009774 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009775 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009776 + " pv=" + w.mPolicyVisibility
9777 + " dp=" + w.mDrawPending
9778 + " cdp=" + w.mCommitDrawPending
9779 + " ah=" + w.mAttachedHidden
9780 + " th=" + atoken.hiddenRequested
9781 + " a=" + w.mAnimating);
9782 }
9783 }
9784 if (w != atoken.startingWindow) {
9785 if (!atoken.freezingScreen || !w.mAppFreezing) {
9786 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009787 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009789 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009790 "tokenMayBeDrawn: " + atoken
9791 + " freezingScreen=" + atoken.freezingScreen
9792 + " mAppFreezing=" + w.mAppFreezing);
9793 tokenMayBeDrawn = true;
9794 }
9795 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009796 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 atoken.startingDisplayed = true;
9798 }
9799 }
9800 } else if (w.mReadyToShow) {
9801 w.performShowLocked();
9802 }
9803 }
9804
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009805 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806
9807 if (tokenMayBeDrawn) {
9808 // See if any windows have been drawn, so they (and others
9809 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009810 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009811 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009812 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813 if (wtoken.freezingScreen) {
9814 int numInteresting = wtoken.numInterestingWindows;
9815 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009816 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 "allDrawn: " + wtoken
9818 + " interesting=" + numInteresting
9819 + " drawn=" + wtoken.numDrawnWindows);
9820 wtoken.showAllWindowsLocked();
9821 unsetAppFreezingScreenLocked(wtoken, false, true);
9822 orientationChangeComplete = true;
9823 }
9824 } else if (!wtoken.allDrawn) {
9825 int numInteresting = wtoken.numInterestingWindows;
9826 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009827 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 "allDrawn: " + wtoken
9829 + " interesting=" + numInteresting
9830 + " drawn=" + wtoken.numDrawnWindows);
9831 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009832 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833
9834 // We can now show all of the drawn windows!
9835 if (!mOpeningApps.contains(wtoken)) {
9836 wtoken.showAllWindowsLocked();
9837 }
9838 }
9839 }
9840 }
9841 }
9842
9843 // If we are ready to perform an app transition, check through
9844 // all of the app tokens to be shown and see if they are ready
9845 // to go.
9846 if (mAppTransitionReady) {
9847 int NN = mOpeningApps.size();
9848 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009849 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009850 "Checking " + NN + " opening apps (frozen="
9851 + mDisplayFrozen + " timeout="
9852 + mAppTransitionTimeout + ")...");
9853 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9854 // If the display isn't frozen, wait to do anything until
9855 // all of the apps are ready. Otherwise just go because
9856 // we'll unfreeze the display when everyone is ready.
9857 for (i=0; i<NN && goodToGo; i++) {
9858 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009859 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 "Check opening app" + wtoken + ": allDrawn="
9861 + wtoken.allDrawn + " startingDisplayed="
9862 + wtoken.startingDisplayed);
9863 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9864 && !wtoken.startingMoved) {
9865 goodToGo = false;
9866 }
9867 }
9868 }
9869 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009870 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009871 int transit = mNextAppTransition;
9872 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009873 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009875 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009876 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009877 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 mAppTransitionTimeout = false;
9879 mStartingIconInTransition = false;
9880 mSkipAppTransitionAnimation = false;
9881
9882 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9883
Dianne Hackborna8f60182009-09-01 19:01:50 -07009884 // If there are applications waiting to come to the
9885 // top of the stack, now is the time to move their windows.
9886 // (Note that we don't do apps going to the bottom
9887 // here -- we want to keep their windows in the old
9888 // Z-order until the animation completes.)
9889 if (mToTopApps.size() > 0) {
9890 NN = mAppTokens.size();
9891 for (i=0; i<NN; i++) {
9892 AppWindowToken wtoken = mAppTokens.get(i);
9893 if (wtoken.sendingToTop) {
9894 wtoken.sendingToTop = false;
9895 moveAppWindowsLocked(wtoken, NN, false);
9896 }
9897 }
9898 mToTopApps.clear();
9899 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009900
Dianne Hackborn25994b42009-09-04 14:21:19 -07009901 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009902
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009903 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009904 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009905
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009906 // The top-most window will supply the layout params,
9907 // and we will determine it below.
9908 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009909 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009910 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009911
Joe Onorato8a9b2202010-02-26 18:56:32 -08009912 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009913 "New wallpaper target=" + mWallpaperTarget
9914 + ", lower target=" + mLowerWallpaperTarget
9915 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009916 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009917 // Do a first pass through the tokens for two
9918 // things:
9919 // (1) Determine if both the closing and opening
9920 // app token sets are wallpaper targets, in which
9921 // case special animations are needed
9922 // (since the wallpaper needs to stay static
9923 // behind them).
9924 // (2) Find the layout params of the top-most
9925 // application window in the tokens, which is
9926 // what will control the animation theme.
9927 final int NC = mClosingApps.size();
9928 NN = NC + mOpeningApps.size();
9929 for (i=0; i<NN; i++) {
9930 AppWindowToken wtoken;
9931 int mode;
9932 if (i < NC) {
9933 wtoken = mClosingApps.get(i);
9934 mode = 1;
9935 } else {
9936 wtoken = mOpeningApps.get(i-NC);
9937 mode = 2;
9938 }
9939 if (mLowerWallpaperTarget != null) {
9940 if (mLowerWallpaperTarget.mAppToken == wtoken
9941 || mUpperWallpaperTarget.mAppToken == wtoken) {
9942 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009943 }
9944 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009945 if (wtoken.appFullscreen) {
9946 WindowState ws = wtoken.findMainWindow();
9947 if (ws != null) {
9948 // If this is a compatibility mode
9949 // window, we will always use its anim.
9950 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9951 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009952 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009953 bestAnimLayer = Integer.MAX_VALUE;
9954 } else if (ws.mLayer > bestAnimLayer) {
9955 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009956 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009957 bestAnimLayer = ws.mLayer;
9958 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009959 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009960 }
9961 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009962
Dianne Hackborn25994b42009-09-04 14:21:19 -07009963 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009964 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009965 "Wallpaper animation!");
9966 switch (transit) {
9967 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9968 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9969 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9970 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9971 break;
9972 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9973 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9974 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9975 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9976 break;
9977 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009978 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009979 "New transit: " + transit);
9980 } else if (oldWallpaper != null) {
9981 // We are transitioning from an activity with
9982 // a wallpaper to one without.
9983 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009984 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009985 "New transit away from wallpaper: " + transit);
9986 } else if (mWallpaperTarget != null) {
9987 // We are transitioning from an activity without
9988 // a wallpaper to now showing the wallpaper
9989 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009990 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009991 "New transit into wallpaper: " + transit);
9992 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009993
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009994 // If all closing windows are obscured, then there is
9995 // no need to do an animation. This is the case, for
9996 // example, when this transition is being done behind
9997 // the lock screen.
9998 if (!mPolicy.allowAppAnimationsLw()) {
9999 animLp = null;
10000 }
10001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010002 NN = mOpeningApps.size();
10003 for (i=0; i<NN; i++) {
10004 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010005 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 "Now opening app" + wtoken);
10007 wtoken.reportedVisible = false;
10008 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010009 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010010 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010011 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010012 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010013 wtoken.showAllWindowsLocked();
10014 }
10015 NN = mClosingApps.size();
10016 for (i=0; i<NN; i++) {
10017 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010018 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019 "Now closing app" + wtoken);
10020 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010021 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010022 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010023 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010024 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 // Force the allDrawn flag, because we want to start
10026 // this guy's animations regardless of whether it's
10027 // gotten drawn.
10028 wtoken.allDrawn = true;
10029 }
10030
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010031 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 mOpeningApps.clear();
10034 mClosingApps.clear();
10035
10036 // This has changed the visibility of windows, so perform
10037 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010038 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010040 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10041 assignLayersLocked();
10042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010044 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010045 }
10046 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010047
Dianne Hackborn16064f92010-03-25 00:47:24 -070010048 int adjResult = 0;
10049
Dianne Hackborna8f60182009-09-01 19:01:50 -070010050 if (!animating && mAppTransitionRunning) {
10051 // We have finished the animation of an app transition. To do
10052 // this, we have delayed a lot of operations like showing and
10053 // hiding apps, moving apps in Z-order, etc. The app token list
10054 // reflects the correct Z-order, but the window list may now
10055 // be out of sync with it. So here we will just rebuild the
10056 // entire app window list. Fun!
10057 mAppTransitionRunning = false;
10058 // Clear information about apps that were moving.
10059 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010060
Dianne Hackborna8f60182009-09-01 19:01:50 -070010061 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010062 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010063 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010064 moveInputMethodWindowsIfNeededLocked(false);
10065 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010066 // Since the window list has been rebuilt, focus might
10067 // have to be recomputed since the actual order of windows
10068 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010069 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010070 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010071
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010072 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010073 // At this point, there was a window with a wallpaper that
10074 // was force hiding other windows behind it, but now it
10075 // is going away. This may be simple -- just animate
10076 // away the wallpaper and its window -- or it may be
10077 // hard -- the wallpaper now needs to be shown behind
10078 // something that was hidden.
10079 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010080 if (mLowerWallpaperTarget != null
10081 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010082 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010083 "wallpaperForceHiding changed with lower="
10084 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010085 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010086 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10087 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10088 if (mLowerWallpaperTarget.mAppToken.hidden) {
10089 // The lower target has become hidden before we
10090 // actually started the animation... let's completely
10091 // re-evaluate everything.
10092 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010093 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010094 }
10095 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010096 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010097 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010098 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010099 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010100 + " NEW: " + mWallpaperTarget
10101 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010102 if (mLowerWallpaperTarget == null) {
10103 // Whoops, we don't need a special wallpaper animation.
10104 // Clear them out.
10105 forceHiding = false;
10106 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010107 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010108 if (w.mSurface != null) {
10109 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010110 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010111 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010112 forceHiding = true;
10113 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10114 if (!w.mAnimating) {
10115 // We set the animation above so it
10116 // is not yet running.
10117 w.clearAnimation();
10118 }
10119 }
10120 }
10121 }
10122 }
10123 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010124
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080010125 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
10126 if (DEBUG_WALLPAPER) Slog.v(TAG,
10127 "Detached wallpaper changed from " + mWindowDetachedWallpaper
10128 + windowDetachedWallpaper);
10129 mWindowDetachedWallpaper = windowDetachedWallpaper;
10130 wallpaperMayChange = true;
10131 }
10132
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010133 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010134 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010135 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010136 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010137 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010138
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010139 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010140 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010141 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010142 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010143 assignLayersLocked();
10144 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010145 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010146 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010147 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010148 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010149
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010150 if (mFocusMayChange) {
10151 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010152 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010153 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010154 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010155 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010156 }
10157
10158 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010159 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010160 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010161
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010162 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10163 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010164
Jeff Browne33348b2010-07-15 23:54:05 -070010165 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010166 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167
10168 // THIRD LOOP: Update the surfaces of all windows.
10169
10170 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10171
10172 boolean obscured = false;
10173 boolean blurring = false;
10174 boolean dimming = false;
10175 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010176 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010177 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010178
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010179 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010182 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183
10184 boolean displayed = false;
10185 final WindowManager.LayoutParams attrs = w.mAttrs;
10186 final int attrFlags = attrs.flags;
10187
10188 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010189 // XXX NOTE: The logic here could be improved. We have
10190 // the decision about whether to resize a window separated
10191 // from whether to hide the surface. This can cause us to
10192 // resize a surface even if we are going to hide it. You
10193 // can see this by (1) holding device in landscape mode on
10194 // home screen; (2) tapping browser icon (device will rotate
10195 // to landscape; (3) tap home. The wallpaper will be resized
10196 // in step 2 but then immediately hidden, causing us to
10197 // have to resize and then redraw it again in step 3. It
10198 // would be nice to figure out how to avoid this, but it is
10199 // difficult because we do need to resize surfaces in some
10200 // cases while they are hidden such as when first showing a
10201 // window.
10202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010203 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010204 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205 TAG, "Placing surface #" + i + " " + w.mSurface
10206 + ": new=" + w.mShownFrame + ", old="
10207 + w.mLastShownFrame);
10208
10209 boolean resize;
10210 int width, height;
10211 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10212 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10213 w.mLastRequestedHeight != w.mRequestedHeight;
10214 // for a scaled surface, we just want to use
10215 // the requested size.
10216 width = w.mRequestedWidth;
10217 height = w.mRequestedHeight;
10218 w.mLastRequestedWidth = width;
10219 w.mLastRequestedHeight = height;
10220 w.mLastShownFrame.set(w.mShownFrame);
10221 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010222 if (SHOW_TRANSACTIONS) logSurface(w,
10223 "POS " + w.mShownFrame.left
10224 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010225 w.mSurfaceX = w.mShownFrame.left;
10226 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010227 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10228 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010229 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 if (!recoveringMemory) {
10231 reclaimSomeSurfaceMemoryLocked(w, "position");
10232 }
10233 }
10234 } else {
10235 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10236 width = w.mShownFrame.width();
10237 height = w.mShownFrame.height();
10238 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 }
10240
10241 if (resize) {
10242 if (width < 1) width = 1;
10243 if (height < 1) height = 1;
10244 if (w.mSurface != null) {
10245 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010246 if (SHOW_TRANSACTIONS) logSurface(w,
10247 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010248 + w.mShownFrame.top + " SIZE "
10249 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010250 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010251 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010252 w.mSurfaceW = width;
10253 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010255 w.mSurfaceX = w.mShownFrame.left;
10256 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010257 w.mSurface.setPosition(w.mShownFrame.left,
10258 w.mShownFrame.top);
10259 } catch (RuntimeException e) {
10260 // If something goes wrong with the surface (such
10261 // as running out of memory), don't take down the
10262 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010263 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010264 + "size=(" + width + "x" + height
10265 + "), pos=(" + w.mShownFrame.left
10266 + "," + w.mShownFrame.top + ")", e);
10267 if (!recoveringMemory) {
10268 reclaimSomeSurfaceMemoryLocked(w, "size");
10269 }
10270 }
10271 }
10272 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010273 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 w.mContentInsetsChanged =
10275 !w.mLastContentInsets.equals(w.mContentInsets);
10276 w.mVisibleInsetsChanged =
10277 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010278 boolean configChanged =
10279 w.mConfiguration != mCurConfiguration
10280 && (w.mConfiguration == null
10281 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010282 if (DEBUG_CONFIGURATION && configChanged) {
10283 Slog.v(TAG, "Win " + w + " config changed: "
10284 + mCurConfiguration);
10285 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010286 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010287 + ": configChanged=" + configChanged
10288 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010289 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010291 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010292 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010293 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 w.mLastFrame.set(w.mFrame);
10295 w.mLastContentInsets.set(w.mContentInsets);
10296 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010297 // If the screen is currently frozen, then keep
10298 // it frozen until this window draws at its new
10299 // orientation.
10300 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010301 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010302 "Resizing while display frozen: " + w);
10303 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010304 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010305 mWindowsFreezingScreen = true;
10306 // XXX should probably keep timeout from
10307 // when we first froze the display.
10308 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10309 mH.sendMessageDelayed(mH.obtainMessage(
10310 H.WINDOW_FREEZE_TIMEOUT), 2000);
10311 }
10312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010313 // If the orientation is changing, then we need to
10314 // hold off on unfreezing the display until this
10315 // window has been redrawn; to do that, we need
10316 // to go through the process of getting informed
10317 // by the application when it has finished drawing.
10318 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010319 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320 "Orientation start waiting for draw in "
10321 + w + ", surface " + w.mSurface);
10322 w.mDrawPending = true;
10323 w.mCommitDrawPending = false;
10324 w.mReadyToShow = false;
10325 if (w.mAppToken != null) {
10326 w.mAppToken.allDrawn = false;
10327 }
10328 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010329 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 "Resizing window " + w + " to " + w.mFrame);
10331 mResizingWindows.add(w);
10332 } else if (w.mOrientationChanging) {
10333 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010334 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010335 "Orientation not waiting for draw in "
10336 + w + ", surface " + w.mSurface);
10337 w.mOrientationChanging = false;
10338 }
10339 }
10340 }
10341
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010342 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010343 if (!w.mLastHidden) {
10344 //dump();
10345 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010346 if (SHOW_TRANSACTIONS) logSurface(w,
10347 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010348 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010349 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 try {
10351 w.mSurface.hide();
10352 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010353 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010354 }
10355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010356 }
10357 // If we are waiting for this window to handle an
10358 // orientation change, well, it is hidden, so
10359 // doesn't really matter. Note that this does
10360 // introduce a potential glitch if the window
10361 // becomes unhidden before it has drawn for the
10362 // new orientation.
10363 if (w.mOrientationChanging) {
10364 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010365 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 "Orientation change skips hidden " + w);
10367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010368 } else if (w.mLastLayer != w.mAnimLayer
10369 || w.mLastAlpha != w.mShownAlpha
10370 || w.mLastDsDx != w.mDsDx
10371 || w.mLastDtDx != w.mDtDx
10372 || w.mLastDsDy != w.mDsDy
10373 || w.mLastDtDy != w.mDtDy
10374 || w.mLastHScale != w.mHScale
10375 || w.mLastVScale != w.mVScale
10376 || w.mLastHidden) {
10377 displayed = true;
10378 w.mLastAlpha = w.mShownAlpha;
10379 w.mLastLayer = w.mAnimLayer;
10380 w.mLastDsDx = w.mDsDx;
10381 w.mLastDtDx = w.mDtDx;
10382 w.mLastDsDy = w.mDsDy;
10383 w.mLastDtDy = w.mDtDy;
10384 w.mLastHScale = w.mHScale;
10385 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010386 if (SHOW_TRANSACTIONS) logSurface(w,
10387 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010388 + " matrix=[" + (w.mDsDx*w.mHScale)
10389 + "," + (w.mDtDx*w.mVScale)
10390 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010391 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 if (w.mSurface != null) {
10393 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010394 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010395 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010396 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 w.mSurface.setLayer(w.mAnimLayer);
10398 w.mSurface.setMatrix(
10399 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10400 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10401 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010402 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010403 if (!recoveringMemory) {
10404 reclaimSomeSurfaceMemoryLocked(w, "update");
10405 }
10406 }
10407 }
10408
10409 if (w.mLastHidden && !w.mDrawPending
10410 && !w.mCommitDrawPending
10411 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010412 if (SHOW_TRANSACTIONS) logSurface(w,
10413 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010414 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010415 + " during relayout");
10416 if (showSurfaceRobustlyLocked(w)) {
10417 w.mHasDrawn = true;
10418 w.mLastHidden = false;
10419 } else {
10420 w.mOrientationChanging = false;
10421 }
10422 }
10423 if (w.mSurface != null) {
10424 w.mToken.hasVisible = true;
10425 }
10426 } else {
10427 displayed = true;
10428 }
10429
10430 if (displayed) {
10431 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010432 if (attrs.width == LayoutParams.MATCH_PARENT
10433 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434 covered = true;
10435 }
10436 }
10437 if (w.mOrientationChanging) {
10438 if (w.mDrawPending || w.mCommitDrawPending) {
10439 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010440 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010441 "Orientation continue waiting for draw in " + w);
10442 } else {
10443 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010444 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 "Orientation change complete in " + w);
10446 }
10447 }
10448 w.mToken.hasVisible = true;
10449 }
10450 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 "Orientation change skips hidden " + w);
10453 w.mOrientationChanging = false;
10454 }
10455
Dianne Hackborn0f761d62010-11-30 22:06:10 -080010456 if (w.mContentChanged) {
10457 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
10458 w.mContentChanged = false;
10459 }
10460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010461 final boolean canBeSeen = w.isDisplayedLw();
10462
10463 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10464 focusDisplayed = true;
10465 }
10466
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010467 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010470 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 if (w.mSurface != null) {
10472 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10473 holdScreen = w.mSession;
10474 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010475 if (!syswin && w.mAttrs.screenBrightness >= 0
10476 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010477 screenBrightness = w.mAttrs.screenBrightness;
10478 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010479 if (!syswin && w.mAttrs.buttonBrightness >= 0
10480 && buttonBrightness < 0) {
10481 buttonBrightness = w.mAttrs.buttonBrightness;
10482 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010483 if (canBeSeen
10484 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10485 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10486 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010487 syswin = true;
10488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010490
Dianne Hackborn25994b42009-09-04 14:21:19 -070010491 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10492 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010493 // This window completely covers everything behind it,
10494 // so we want to leave all of them as unblurred (for
10495 // performance reasons).
10496 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010497 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010498 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010499 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010500 obscured = true;
10501 if (mBackgroundFillerSurface == null) {
10502 try {
10503 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010504 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010505 0, dw, dh,
10506 PixelFormat.OPAQUE,
10507 Surface.FX_SURFACE_NORMAL);
10508 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010509 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010510 }
10511 }
10512 try {
10513 mBackgroundFillerSurface.setPosition(0, 0);
10514 mBackgroundFillerSurface.setSize(dw, dh);
10515 // Using the same layer as Dim because they will never be shown at the
10516 // same time.
10517 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10518 mBackgroundFillerSurface.show();
10519 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010520 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010521 }
10522 backgroundFillerShown = true;
10523 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010524 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010525 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010526 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 + ": blurring=" + blurring
10528 + " obscured=" + obscured
10529 + " displayed=" + displayed);
10530 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10531 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010532 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010534 if (mDimAnimator == null) {
10535 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010537 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -080010538 mDimAnimator.updateParameters(mContext.getResources(),
10539 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010541 }
10542 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10543 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010544 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010545 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010547 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 + mBlurSurface + ": CREATE");
10549 try {
Romain Guy06882f82009-06-10 13:36:04 -070010550 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010551 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010552 -1, 16, 16,
10553 PixelFormat.OPAQUE,
10554 Surface.FX_SURFACE_BLUR);
10555 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010556 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010557 }
10558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010559 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010560 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10561 + mBlurSurface + ": pos=(0,0) (" +
10562 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010563 mBlurSurface.setPosition(0, 0);
10564 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010565 mBlurSurface.setLayer(w.mAnimLayer-2);
10566 if (!mBlurShown) {
10567 try {
10568 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10569 + mBlurSurface + ": SHOW");
10570 mBlurSurface.show();
10571 } catch (RuntimeException e) {
10572 Slog.w(TAG, "Failure showing blur surface", e);
10573 }
10574 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010575 }
10576 }
10577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010578 }
10579 }
10580 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010581
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010582 if (obscuredChanged && mWallpaperTarget == w) {
10583 // This is the wallpaper target and its obscured state
10584 // changed... make sure the current wallaper's visibility
10585 // has been updated accordingly.
10586 updateWallpaperVisibilityLocked();
10587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010589
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010590 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10591 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010592 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010593 try {
10594 mBackgroundFillerSurface.hide();
10595 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010596 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010597 }
10598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010600 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010601 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10602 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010603 }
Romain Guy06882f82009-06-10 13:36:04 -070010604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010606 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 + ": HIDE");
10608 try {
10609 mBlurSurface.hide();
10610 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010611 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010612 }
10613 mBlurShown = false;
10614 }
10615
Joe Onorato8a9b2202010-02-26 18:56:32 -080010616 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010617 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010618 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010619 }
10620
Jeff Browne33348b2010-07-15 23:54:05 -070010621 mInputMonitor.updateInputWindowsLw();
10622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010623 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010624
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010625 if (mWatermark != null) {
10626 mWatermark.drawIfNeeded();
10627 }
10628
Joe Onorato8a9b2202010-02-26 18:56:32 -080010629 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010630 "With display frozen, orientationChangeComplete="
10631 + orientationChangeComplete);
10632 if (orientationChangeComplete) {
10633 if (mWindowsFreezingScreen) {
10634 mWindowsFreezingScreen = false;
10635 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10636 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010637 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010638 }
Romain Guy06882f82009-06-10 13:36:04 -070010639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640 i = mResizingWindows.size();
10641 if (i > 0) {
10642 do {
10643 i--;
10644 WindowState win = mResizingWindows.get(i);
10645 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010646 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10647 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010648 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010649 boolean configChanged =
10650 win.mConfiguration != mCurConfiguration
10651 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010652 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10653 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10654 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010655 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010656 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010657 + " / " + mCurConfiguration + " / 0x"
10658 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010659 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010660 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010661 win.mClient.resized(win.mFrame.width(),
10662 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010663 win.mLastVisibleInsets, win.mDrawPending,
10664 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010665 win.mContentInsetsChanged = false;
10666 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010667 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010668 } catch (RemoteException e) {
10669 win.mOrientationChanging = false;
10670 }
10671 } while (i > 0);
10672 mResizingWindows.clear();
10673 }
Romain Guy06882f82009-06-10 13:36:04 -070010674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010676 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010677 i = mDestroySurface.size();
10678 if (i > 0) {
10679 do {
10680 i--;
10681 WindowState win = mDestroySurface.get(i);
10682 win.mDestroying = false;
10683 if (mInputMethodWindow == win) {
10684 mInputMethodWindow = null;
10685 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010686 if (win == mWallpaperTarget) {
10687 wallpaperDestroyed = true;
10688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 win.destroySurfaceLocked();
10690 } while (i > 0);
10691 mDestroySurface.clear();
10692 }
10693
10694 // Time to remove any exiting tokens?
10695 for (i=mExitingTokens.size()-1; i>=0; i--) {
10696 WindowToken token = mExitingTokens.get(i);
10697 if (!token.hasVisible) {
10698 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010699 if (token.windowType == TYPE_WALLPAPER) {
10700 mWallpaperTokens.remove(token);
10701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 }
10703 }
10704
10705 // Time to remove any exiting applications?
10706 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10707 AppWindowToken token = mExitingAppTokens.get(i);
10708 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010709 // Make sure there is no animation running on this token,
10710 // so any windows associated with it will be removed as
10711 // soon as their animations are complete
10712 token.animation = null;
10713 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080010714 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
10715 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010716 mAppTokens.remove(token);
10717 mExitingAppTokens.remove(i);
10718 }
10719 }
10720
Dianne Hackborna8f60182009-09-01 19:01:50 -070010721 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010722
Dianne Hackborna8f60182009-09-01 19:01:50 -070010723 if (!animating && mAppTransitionRunning) {
10724 // We have finished the animation of an app transition. To do
10725 // this, we have delayed a lot of operations like showing and
10726 // hiding apps, moving apps in Z-order, etc. The app token list
10727 // reflects the correct Z-order, but the window list may now
10728 // be out of sync with it. So here we will just rebuild the
10729 // entire app window list. Fun!
10730 mAppTransitionRunning = false;
10731 needRelayout = true;
10732 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010733 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010734 // Clear information about apps that were moving.
10735 mToBottomApps.clear();
10736 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 if (focusDisplayed) {
10739 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10740 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010741 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010742 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010743 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010744 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010745 requestAnimationLocked(0);
10746 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010747 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10748 }
Jeff Browneb857f12010-07-16 10:06:33 -070010749
Jeff Browne33348b2010-07-15 23:54:05 -070010750 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010751
Jeff Brown8e03b752010-06-13 19:16:55 -070010752 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10754 mPowerManager.setScreenBrightnessOverride(-1);
10755 } else {
10756 mPowerManager.setScreenBrightnessOverride((int)
10757 (screenBrightness * Power.BRIGHTNESS_ON));
10758 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010759 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10760 mPowerManager.setButtonBrightnessOverride(-1);
10761 } else {
10762 mPowerManager.setButtonBrightnessOverride((int)
10763 (buttonBrightness * Power.BRIGHTNESS_ON));
10764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 if (holdScreen != mHoldingScreenOn) {
10766 mHoldingScreenOn = holdScreen;
10767 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10768 mH.sendMessage(m);
10769 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010770
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010771 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010772 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010773 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10774 LocalPowerManager.BUTTON_EVENT, true);
10775 mTurnOnScreen = false;
10776 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010777
10778 // Check to see if we are now in a state where the screen should
10779 // be enabled, because the window obscured flags have changed.
10780 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010782
10783 /**
10784 * Must be called with the main window manager lock held.
10785 */
10786 void setHoldScreenLocked(boolean holding) {
10787 boolean state = mHoldingScreenWakeLock.isHeld();
10788 if (holding != state) {
10789 if (holding) {
10790 mHoldingScreenWakeLock.acquire();
10791 } else {
10792 mPolicy.screenOnStoppedLw();
10793 mHoldingScreenWakeLock.release();
10794 }
10795 }
10796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797
10798 void requestAnimationLocked(long delay) {
10799 if (!mAnimationPending) {
10800 mAnimationPending = true;
10801 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10802 }
10803 }
Romain Guy06882f82009-06-10 13:36:04 -070010804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 /**
10806 * Have the surface flinger show a surface, robustly dealing with
10807 * error conditions. In particular, if there is not enough memory
10808 * to show the surface, then we will try to get rid of other surfaces
10809 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010810 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010811 * @return Returns true if the surface was successfully shown.
10812 */
10813 boolean showSurfaceRobustlyLocked(WindowState win) {
10814 try {
10815 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010816 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010818 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010819 if (DEBUG_VISIBILITY) Slog.v(TAG,
10820 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010821 win.mTurnOnScreen = false;
10822 mTurnOnScreen = true;
10823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 }
10825 return true;
10826 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010827 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010828 }
Romain Guy06882f82009-06-10 13:36:04 -070010829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010832 return false;
10833 }
Romain Guy06882f82009-06-10 13:36:04 -070010834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010835 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10836 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010837
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010838 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010839 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 if (mForceRemoves == null) {
10842 mForceRemoves = new ArrayList<WindowState>();
10843 }
Romain Guy06882f82009-06-10 13:36:04 -070010844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 long callingIdentity = Binder.clearCallingIdentity();
10846 try {
10847 // There was some problem... first, do a sanity check of the
10848 // window list to make sure we haven't left any dangling surfaces
10849 // around.
10850 int N = mWindows.size();
10851 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010852 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010853 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010854 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 if (ws.mSurface != null) {
10856 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010857 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010858 + ws + " surface=" + ws.mSurface
10859 + " token=" + win.mToken
10860 + " pid=" + ws.mSession.mPid
10861 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010862 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010863 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010864 ws.mSurface = null;
10865 mForceRemoves.add(ws);
10866 i--;
10867 N--;
10868 leakedSurface = true;
10869 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010870 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 + ws + " surface=" + ws.mSurface
10872 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010873 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010874 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010875 ws.mSurface = null;
10876 leakedSurface = true;
10877 }
10878 }
10879 }
Romain Guy06882f82009-06-10 13:36:04 -070010880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 boolean killedApps = false;
10882 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010883 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010884 SparseIntArray pidCandidates = new SparseIntArray();
10885 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010886 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010887 if (ws.mSurface != null) {
10888 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10889 }
10890 }
10891 if (pidCandidates.size() > 0) {
10892 int[] pids = new int[pidCandidates.size()];
10893 for (int i=0; i<pids.length; i++) {
10894 pids[i] = pidCandidates.keyAt(i);
10895 }
10896 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010897 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 killedApps = true;
10899 }
10900 } catch (RemoteException e) {
10901 }
10902 }
10903 }
Romain Guy06882f82009-06-10 13:36:04 -070010904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 if (leakedSurface || killedApps) {
10906 // We managed to reclaim some memory, so get rid of the trouble
10907 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010908 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010910 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010911 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 win.mSurface = null;
10913 }
Romain Guy06882f82009-06-10 13:36:04 -070010914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 try {
10916 win.mClient.dispatchGetNewSurface();
10917 } catch (RemoteException e) {
10918 }
10919 }
10920 } finally {
10921 Binder.restoreCallingIdentity(callingIdentity);
10922 }
10923 }
Romain Guy06882f82009-06-10 13:36:04 -070010924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 private boolean updateFocusedWindowLocked(int mode) {
10926 WindowState newFocus = computeFocusedWindowLocked();
10927 if (mCurrentFocus != newFocus) {
10928 // This check makes sure that we don't already have the focus
10929 // change message pending.
10930 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10931 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010932 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010933 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10934 final WindowState oldFocus = mCurrentFocus;
10935 mCurrentFocus = newFocus;
10936 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010938 final WindowState imWindow = mInputMethodWindow;
10939 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010940 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010941 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010942 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10943 mLayoutNeeded = true;
10944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010945 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -080010946 performLayoutLockedInner(true);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010947 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10948 // Client will do the layout, but we need to assign layers
10949 // for handleNewWindowLocked() below.
10950 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010951 }
10952 }
Jeff Brown349703e2010-06-22 01:27:15 -070010953
10954 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10955 // If we defer assigning layers, then the caller is responsible for
10956 // doing this part.
10957 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010959 return true;
10960 }
10961 return false;
10962 }
Jeff Brown349703e2010-06-22 01:27:15 -070010963
10964 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010965 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967
10968 private WindowState computeFocusedWindowLocked() {
10969 WindowState result = null;
10970 WindowState win;
10971
10972 int i = mWindows.size() - 1;
10973 int nextAppIndex = mAppTokens.size()-1;
10974 WindowToken nextApp = nextAppIndex >= 0
10975 ? mAppTokens.get(nextAppIndex) : null;
10976
10977 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010978 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979
Joe Onorato8a9b2202010-02-26 18:56:32 -080010980 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010981 TAG, "Looking for focus: " + i
10982 + " = " + win
10983 + ", flags=" + win.mAttrs.flags
10984 + ", canReceive=" + win.canReceiveKeys());
10985
10986 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 // If this window's application has been removed, just skip it.
10989 if (thisApp != null && thisApp.removed) {
10990 i--;
10991 continue;
10992 }
Romain Guy06882f82009-06-10 13:36:04 -070010993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994 // If there is a focused app, don't allow focus to go to any
10995 // windows below it. If this is an application window, step
10996 // through the app tokens until we find its app.
10997 if (thisApp != null && nextApp != null && thisApp != nextApp
10998 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10999 int origAppIndex = nextAppIndex;
11000 while (nextAppIndex > 0) {
11001 if (nextApp == mFocusedApp) {
11002 // Whoops, we are below the focused app... no focus
11003 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011004 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011005 TAG, "Reached focused app: " + mFocusedApp);
11006 return null;
11007 }
11008 nextAppIndex--;
11009 nextApp = mAppTokens.get(nextAppIndex);
11010 if (nextApp == thisApp) {
11011 break;
11012 }
11013 }
11014 if (thisApp != nextApp) {
11015 // Uh oh, the app token doesn't exist! This shouldn't
11016 // happen, but if it does we can get totally hosed...
11017 // so restart at the original app.
11018 nextAppIndex = origAppIndex;
11019 nextApp = mAppTokens.get(nextAppIndex);
11020 }
11021 }
11022
11023 // Dispatch to this window if it is wants key events.
11024 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011025 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 TAG, "Found focus @ " + i + " = " + win);
11027 result = win;
11028 break;
11029 }
11030
11031 i--;
11032 }
11033
11034 return result;
11035 }
11036
11037 private void startFreezingDisplayLocked() {
11038 if (mDisplayFrozen) {
11039 return;
11040 }
Romain Guy06882f82009-06-10 13:36:04 -070011041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011042 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011045 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 if (mFreezeGcPending != 0) {
11047 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011048 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011049 mH.removeMessages(H.FORCE_GC);
11050 Runtime.getRuntime().gc();
11051 mFreezeGcPending = now;
11052 }
11053 } else {
11054 mFreezeGcPending = now;
11055 }
Romain Guy06882f82009-06-10 13:36:04 -070011056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011057 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070011058
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011059 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070011060
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011061 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11062 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011063 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011064 mAppTransitionReady = true;
11065 }
Romain Guy06882f82009-06-10 13:36:04 -070011066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 if (PROFILE_ORIENTATION) {
11068 File file = new File("/data/system/frozen");
11069 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11070 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011071
11072 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011073 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
11074 mScreenRotationAnimation.kill();
11075 mScreenRotationAnimation = null;
11076 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011077 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011078 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
11079 mDisplay, mFxSession);
Dianne Hackborna1111872010-11-23 20:55:11 -080011080 }
11081 } else {
11082 Surface.freezeDisplay(0);
11083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011084 }
Romain Guy06882f82009-06-10 13:36:04 -070011085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011086 private void stopFreezingDisplayLocked() {
11087 if (!mDisplayFrozen) {
11088 return;
11089 }
Romain Guy06882f82009-06-10 13:36:04 -070011090
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011091 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11092 return;
11093 }
11094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011095 mDisplayFrozen = false;
11096 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11097 if (PROFILE_ORIENTATION) {
11098 Debug.stopMethodTracing();
11099 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011100
11101 if (CUSTOM_SCREEN_ROTATION) {
11102 if (mScreenRotationAnimation != null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011103 if (mScreenRotationAnimation.dismiss(MAX_ANIMATION_DURATION,
11104 mTransitionAnimationScale)) {
11105 requestAnimationLocked(0);
11106 } else {
11107 mScreenRotationAnimation = null;
11108 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011109 }
11110 } else {
11111 Surface.unfreezeDisplay(0);
11112 }
Romain Guy06882f82009-06-10 13:36:04 -070011113
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011114 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115
Christopher Tateb696aee2010-04-02 19:08:30 -070011116 // While the display is frozen we don't re-compute the orientation
11117 // to avoid inconsistent states. However, something interesting
11118 // could have actually changed during that time so re-evaluate it
11119 // now to catch that.
11120 if (updateOrientationFromAppTokensLocked()) {
11121 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11122 }
11123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011124 // A little kludge: a lot could have happened while the
11125 // display was frozen, so now that we are coming back we
11126 // do a gc so that any remote references the system
11127 // processes holds on others can be released if they are
11128 // no longer needed.
11129 mH.removeMessages(H.FORCE_GC);
11130 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11131 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011133 mScreenFrozenLock.release();
11134 }
Romain Guy06882f82009-06-10 13:36:04 -070011135
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011136 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
11137 DisplayMetrics dm) {
11138 if (index < tokens.length) {
11139 String str = tokens[index];
11140 if (str != null && str.length() > 0) {
11141 try {
11142 int val = Integer.parseInt(str);
11143 return val;
11144 } catch (Exception e) {
11145 }
11146 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011147 }
11148 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
11149 return defDps;
11150 }
11151 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
11152 return val;
11153 }
11154
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011155 static class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011156 final String[] mTokens;
11157 final String mText;
11158 final Paint mTextPaint;
11159 final int mTextWidth;
11160 final int mTextHeight;
11161 final int mTextAscent;
11162 final int mTextDescent;
11163 final int mDeltaX;
11164 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011165
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011166 Surface mSurface;
11167 int mLastDW;
11168 int mLastDH;
11169 boolean mDrawNeeded;
11170
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011171 Watermark(Display display, SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011172 final DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011173 display.getMetrics(dm);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011174
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011175 if (false) {
11176 Log.i(TAG, "*********************** WATERMARK");
11177 for (int i=0; i<tokens.length; i++) {
11178 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
11179 }
11180 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011181
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011182 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011183
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011184 StringBuilder builder = new StringBuilder(32);
11185 int len = mTokens[0].length();
11186 len = len & ~1;
11187 for (int i=0; i<len; i+=2) {
11188 int c1 = mTokens[0].charAt(i);
11189 int c2 = mTokens[0].charAt(i+1);
11190 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
11191 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
11192 else c1 -= '0';
11193 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
11194 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
11195 else c2 -= '0';
11196 builder.append((char)(255-((c1*16)+c2)));
11197 }
11198 mText = builder.toString();
11199 if (false) {
11200 Log.i(TAG, "Final text: " + mText);
11201 }
11202
11203 int fontSize = getPropertyInt(tokens, 1,
11204 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
11205
11206 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
11207 mTextPaint.setTextSize(fontSize);
11208 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
11209
11210 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
11211 mTextWidth = (int)mTextPaint.measureText(mText);
11212 mTextAscent = fm.ascent;
11213 mTextDescent = fm.descent;
11214 mTextHeight = fm.descent - fm.ascent;
11215
11216 mDeltaX = getPropertyInt(tokens, 2,
11217 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
11218 mDeltaY = getPropertyInt(tokens, 3,
11219 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
11220 int shadowColor = getPropertyInt(tokens, 4,
11221 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
11222 int color = getPropertyInt(tokens, 5,
11223 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
11224 int shadowRadius = getPropertyInt(tokens, 6,
11225 TypedValue.COMPLEX_UNIT_PX, 7, dm);
11226 int shadowDx = getPropertyInt(tokens, 8,
11227 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11228 int shadowDy = getPropertyInt(tokens, 9,
11229 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11230
11231 mTextPaint.setColor(color);
11232 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011233
11234 try {
11235 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011236 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011237 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011238 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011239 mSurface.show();
11240 } catch (OutOfResourcesException e) {
11241 }
11242 }
11243
11244 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011245 if (mLastDW != dw || mLastDH != dh) {
11246 mLastDW = dw;
11247 mLastDH = dh;
11248 mSurface.setSize(dw, dh);
11249 mDrawNeeded = true;
11250 }
11251 }
11252
11253 void drawIfNeeded() {
11254 if (mDrawNeeded) {
11255 final int dw = mLastDW;
11256 final int dh = mLastDH;
11257
11258 mDrawNeeded = false;
11259 Rect dirty = new Rect(0, 0, dw, dh);
11260 Canvas c = null;
11261 try {
11262 c = mSurface.lockCanvas(dirty);
11263 } catch (IllegalArgumentException e) {
11264 } catch (OutOfResourcesException e) {
11265 }
11266 if (c != null) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011267 c.drawColor(0, PorterDuff.Mode.CLEAR);
11268
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011269 int deltaX = mDeltaX;
11270 int deltaY = mDeltaY;
11271
11272 // deltaX shouldn't be close to a round fraction of our
11273 // x step, or else things will line up too much.
11274 int div = (dw+mTextWidth)/deltaX;
11275 int rem = (dw+mTextWidth) - (div*deltaX);
11276 int qdelta = deltaX/4;
11277 if (rem < qdelta || rem > (deltaX-qdelta)) {
11278 deltaX += deltaX/3;
11279 }
11280
11281 int y = -mTextHeight;
11282 int x = -mTextWidth;
11283 while (y < (dh+mTextHeight)) {
11284 c.drawText(mText, x, y, mTextPaint);
11285 x += deltaX;
11286 if (x >= dw) {
11287 x -= (dw+mTextWidth);
11288 y += deltaY;
11289 }
11290 }
11291 mSurface.unlockCanvasAndPost(c);
11292 }
11293 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011294 }
11295 }
11296
11297 void createWatermark() {
11298 if (mWatermark != null) {
11299 return;
11300 }
11301
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011302 File file = new File("/system/etc/setup.conf");
11303 FileInputStream in = null;
11304 try {
11305 in = new FileInputStream(file);
11306 DataInputStream ind = new DataInputStream(in);
11307 String line = ind.readLine();
11308 if (line != null) {
11309 String[] toks = line.split("%");
11310 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011311 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011312 }
11313 }
11314 } catch (FileNotFoundException e) {
11315 } catch (IOException e) {
11316 } finally {
11317 if (in != null) {
11318 try {
11319 in.close();
11320 } catch (IOException e) {
11321 }
11322 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011323 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011324 }
11325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011326 @Override
11327 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11328 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11329 != PackageManager.PERMISSION_GRANTED) {
11330 pw.println("Permission Denial: can't dump WindowManager from from pid="
11331 + Binder.getCallingPid()
11332 + ", uid=" + Binder.getCallingUid());
11333 return;
11334 }
Romain Guy06882f82009-06-10 13:36:04 -070011335
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011336 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080011337 pw.println(" ");
11338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 synchronized(mWindowMap) {
11340 pw.println("Current Window Manager state:");
11341 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070011342 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011343 pw.print(" Window #"); pw.print(i); pw.print(' ');
11344 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 w.dump(pw, " ");
11346 }
11347 if (mInputMethodDialogs.size() > 0) {
11348 pw.println(" ");
11349 pw.println(" Input method dialogs:");
11350 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11351 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011352 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011353 }
11354 }
11355 if (mPendingRemove.size() > 0) {
11356 pw.println(" ");
11357 pw.println(" Remove pending for:");
11358 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11359 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011360 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11361 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011362 w.dump(pw, " ");
11363 }
11364 }
11365 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11366 pw.println(" ");
11367 pw.println(" Windows force removing:");
11368 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11369 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011370 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11371 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 w.dump(pw, " ");
11373 }
11374 }
11375 if (mDestroySurface.size() > 0) {
11376 pw.println(" ");
11377 pw.println(" Windows waiting to destroy their surface:");
11378 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11379 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011380 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11381 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011382 w.dump(pw, " ");
11383 }
11384 }
11385 if (mLosingFocus.size() > 0) {
11386 pw.println(" ");
11387 pw.println(" Windows losing focus:");
11388 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11389 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011390 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11391 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011392 w.dump(pw, " ");
11393 }
11394 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011395 if (mResizingWindows.size() > 0) {
11396 pw.println(" ");
11397 pw.println(" Windows waiting to resize:");
11398 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11399 WindowState w = mResizingWindows.get(i);
11400 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11401 pw.print(w); pw.println(":");
11402 w.dump(pw, " ");
11403 }
11404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 if (mSessions.size() > 0) {
11406 pw.println(" ");
11407 pw.println(" All active sessions:");
11408 Iterator<Session> it = mSessions.iterator();
11409 while (it.hasNext()) {
11410 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011411 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412 s.dump(pw, " ");
11413 }
11414 }
11415 if (mTokenMap.size() > 0) {
11416 pw.println(" ");
11417 pw.println(" All tokens:");
11418 Iterator<WindowToken> it = mTokenMap.values().iterator();
11419 while (it.hasNext()) {
11420 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011421 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011422 token.dump(pw, " ");
11423 }
11424 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011425 if (mWallpaperTokens.size() > 0) {
11426 pw.println(" ");
11427 pw.println(" Wallpaper tokens:");
11428 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11429 WindowToken token = mWallpaperTokens.get(i);
11430 pw.print(" Wallpaper #"); pw.print(i);
11431 pw.print(' '); pw.print(token); pw.println(':');
11432 token.dump(pw, " ");
11433 }
11434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011435 if (mAppTokens.size() > 0) {
11436 pw.println(" ");
11437 pw.println(" Application tokens in Z order:");
11438 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011439 pw.print(" App #"); pw.print(i); pw.print(": ");
11440 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 }
11442 }
11443 if (mFinishedStarting.size() > 0) {
11444 pw.println(" ");
11445 pw.println(" Finishing start of application tokens:");
11446 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11447 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011448 pw.print(" Finished Starting #"); pw.print(i);
11449 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 token.dump(pw, " ");
11451 }
11452 }
11453 if (mExitingTokens.size() > 0) {
11454 pw.println(" ");
11455 pw.println(" Exiting tokens:");
11456 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11457 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011458 pw.print(" Exiting #"); pw.print(i);
11459 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011460 token.dump(pw, " ");
11461 }
11462 }
11463 if (mExitingAppTokens.size() > 0) {
11464 pw.println(" ");
11465 pw.println(" Exiting application tokens:");
11466 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11467 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011468 pw.print(" Exiting App #"); pw.print(i);
11469 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011470 token.dump(pw, " ");
11471 }
11472 }
11473 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011474 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11475 pw.print(" mLastFocus="); pw.println(mLastFocus);
11476 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11477 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11478 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011479 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011480 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11481 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11482 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11483 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080011484 if (mWindowDetachedWallpaper != null) {
11485 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
11486 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011487 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11488 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11489 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011490 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11491 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11492 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11493 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011494 if (mDimAnimator != null) {
11495 mDimAnimator.printTo(pw);
11496 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011497 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011498 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011499 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011500 pw.print(mInputMethodAnimLayerAdjustment);
11501 pw.print(" mWallpaperAnimLayerAdjustment=");
11502 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011503 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11504 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011505 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11506 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011507 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11508 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011509 pw.print(" mRotation="); pw.print(mRotation);
11510 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11511 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11512 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11513 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11514 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11515 pw.print(" mNextAppTransition=0x");
11516 pw.print(Integer.toHexString(mNextAppTransition));
11517 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011518 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011519 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011520 if (mNextAppTransitionPackage != null) {
11521 pw.print(" mNextAppTransitionPackage=");
11522 pw.print(mNextAppTransitionPackage);
11523 pw.print(", mNextAppTransitionEnter=0x");
11524 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11525 pw.print(", mNextAppTransitionExit=0x");
11526 pw.print(Integer.toHexString(mNextAppTransitionExit));
11527 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011528 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11529 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
11530 if (mOpeningApps.size() > 0) {
11531 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11532 }
11533 if (mClosingApps.size() > 0) {
11534 pw.print(" mClosingApps="); pw.println(mClosingApps);
11535 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011536 if (mToTopApps.size() > 0) {
11537 pw.print(" mToTopApps="); pw.println(mToTopApps);
11538 }
11539 if (mToBottomApps.size() > 0) {
11540 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11541 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -080011542 if (mDisplay != null) {
11543 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11544 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
11545 } else {
11546 pw.println(" NO DISPLAY");
11547 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080011548 pw.println(" Policy:");
11549 mPolicy.dump(" ", fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 }
11551 }
11552
Jeff Brown349703e2010-06-22 01:27:15 -070011553 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 public void monitor() {
11555 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011556 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011557 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011558
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011559 /**
11560 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011561 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011562 */
11563 private static class DimAnimator {
11564 Surface mDimSurface;
11565 boolean mDimShown = false;
11566 float mDimCurrentAlpha;
11567 float mDimTargetAlpha;
11568 float mDimDeltaPerMs;
11569 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011570
11571 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011572
11573 DimAnimator (SurfaceSession session) {
11574 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011575 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011576 + mDimSurface + ": CREATE");
11577 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011578 mDimSurface = new Surface(session, 0,
11579 "DimSurface",
11580 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011581 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011582 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011583 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011584 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011585 }
11586 }
11587 }
11588
11589 /**
11590 * Show the dim surface.
11591 */
11592 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011593 if (!mDimShown) {
11594 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11595 dw + "x" + dh + ")");
11596 mDimShown = true;
11597 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011598 mLastDimWidth = dw;
11599 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011600 mDimSurface.setPosition(0, 0);
11601 mDimSurface.setSize(dw, dh);
11602 mDimSurface.show();
11603 } catch (RuntimeException e) {
11604 Slog.w(TAG, "Failure showing dim surface", e);
11605 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011606 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11607 mLastDimWidth = dw;
11608 mLastDimHeight = dh;
11609 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011610 }
11611 }
11612
11613 /**
11614 * Set's the dim surface's layer and update dim parameters that will be used in
11615 * {@link updateSurface} after all windows are examined.
11616 */
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011617 void updateParameters(Resources res, WindowState w, long currentTime) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011618 mDimSurface.setLayer(w.mAnimLayer-1);
11619
11620 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011621 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011622 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011623 if (mDimTargetAlpha != target) {
11624 // If the desired dim level has changed, then
11625 // start an animation to it.
11626 mLastDimAnimTime = currentTime;
11627 long duration = (w.mAnimating && w.mAnimation != null)
11628 ? w.mAnimation.computeDurationHint()
11629 : DEFAULT_DIM_DURATION;
11630 if (target > mDimTargetAlpha) {
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011631 TypedValue tv = new TypedValue();
11632 res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
11633 tv, true);
11634 if (tv.type == TypedValue.TYPE_FRACTION) {
11635 duration = (long)tv.getFraction((float)duration, (float)duration);
11636 } else if (tv.type >= TypedValue.TYPE_FIRST_INT
11637 && tv.type <= TypedValue.TYPE_LAST_INT) {
11638 duration = tv.data;
11639 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011640 }
11641 if (duration < 1) {
11642 // Don't divide by zero
11643 duration = 1;
11644 }
11645 mDimTargetAlpha = target;
11646 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11647 }
11648 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011649
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011650 /**
11651 * Updating the surface's alpha. Returns true if the animation continues, or returns
11652 * false when the animation is finished and the dim surface is hidden.
11653 */
11654 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11655 if (!dimming) {
11656 if (mDimTargetAlpha != 0) {
11657 mLastDimAnimTime = currentTime;
11658 mDimTargetAlpha = 0;
11659 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11660 }
11661 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011662
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011663 boolean animating = false;
11664 if (mLastDimAnimTime != 0) {
11665 mDimCurrentAlpha += mDimDeltaPerMs
11666 * (currentTime-mLastDimAnimTime);
11667 boolean more = true;
11668 if (displayFrozen) {
11669 // If the display is frozen, there is no reason to animate.
11670 more = false;
11671 } else if (mDimDeltaPerMs > 0) {
11672 if (mDimCurrentAlpha > mDimTargetAlpha) {
11673 more = false;
11674 }
11675 } else if (mDimDeltaPerMs < 0) {
11676 if (mDimCurrentAlpha < mDimTargetAlpha) {
11677 more = false;
11678 }
11679 } else {
11680 more = false;
11681 }
11682
11683 // Do we need to continue animating?
11684 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011685 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011686 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11687 mLastDimAnimTime = currentTime;
11688 mDimSurface.setAlpha(mDimCurrentAlpha);
11689 animating = true;
11690 } else {
11691 mDimCurrentAlpha = mDimTargetAlpha;
11692 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011693 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011694 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11695 mDimSurface.setAlpha(mDimCurrentAlpha);
11696 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011697 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011698 + ": HIDE");
11699 try {
11700 mDimSurface.hide();
11701 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011702 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011703 }
11704 mDimShown = false;
11705 }
11706 }
11707 }
11708 return animating;
11709 }
11710
11711 public void printTo(PrintWriter pw) {
11712 pw.print(" mDimShown="); pw.print(mDimShown);
11713 pw.print(" current="); pw.print(mDimCurrentAlpha);
11714 pw.print(" target="); pw.print(mDimTargetAlpha);
11715 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11716 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11717 }
11718 }
11719
11720 /**
11721 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11722 * This is used for opening/closing transition for apps in compatible mode.
11723 */
11724 private static class FadeInOutAnimation extends Animation {
11725 int mWidth;
11726 boolean mFadeIn;
11727
11728 public FadeInOutAnimation(boolean fadeIn) {
11729 setInterpolator(new AccelerateInterpolator());
11730 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11731 mFadeIn = fadeIn;
11732 }
11733
11734 @Override
11735 protected void applyTransformation(float interpolatedTime, Transformation t) {
11736 float x = interpolatedTime;
11737 if (!mFadeIn) {
11738 x = 1.0f - x; // reverse the interpolation for fade out
11739 }
11740 if (x < 0.5) {
11741 // move the window out of the screen.
11742 t.getMatrix().setTranslate(mWidth, 0);
11743 } else {
11744 t.getMatrix().setTranslate(0, 0);// show
11745 t.setAlpha((x - 0.5f) * 2);
11746 }
11747 }
11748
11749 @Override
11750 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11751 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11752 mWidth = width;
11753 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011754
11755 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011756 public int getZAdjustment() {
11757 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011758 }
11759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760}