blob: 833d08eaa507a440b47bb5b3d9c0d023a4305405 [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
19import static android.os.LocalPowerManager.CHEEK_EVENT;
20import static android.os.LocalPowerManager.OTHER_EVENT;
21import static android.os.LocalPowerManager.TOUCH_EVENT;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -070022import static android.os.LocalPowerManager.LONG_TOUCH_EVENT;
23import static android.os.LocalPowerManager.TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
25import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
26import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070027import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
29import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -070030import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR;
32import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
33import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
36import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import static android.view.WindowManager.LayoutParams.MEMORY_TYPE_PUSH_BUFFERS;
38import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
39import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
40import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
41import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070042import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043
44import com.android.internal.app.IBatteryStats;
45import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080046import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import com.android.internal.view.IInputContext;
48import com.android.internal.view.IInputMethodClient;
49import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080050import com.android.internal.view.WindowManagerPolicyThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import com.android.server.am.BatteryStatsService;
52
53import android.Manifest;
54import android.app.ActivityManagerNative;
55import android.app.IActivityManager;
Jim Millerd6b57052010-06-07 17:52:42 -070056import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070057import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070059import android.content.Intent;
60import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.pm.ActivityInfo;
62import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070063import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.content.res.Configuration;
65import android.graphics.Matrix;
66import android.graphics.PixelFormat;
67import android.graphics.Rect;
68import android.graphics.Region;
69import android.os.BatteryStats;
70import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070071import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.Debug;
73import android.os.Handler;
74import android.os.IBinder;
Michael Chan53071d62009-05-13 17:29:48 -070075import android.os.LatencyTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.LocalPowerManager;
77import android.os.Looper;
78import android.os.Message;
79import android.os.Parcel;
80import android.os.ParcelFileDescriptor;
81import android.os.Power;
82import android.os.PowerManager;
83import android.os.Process;
84import android.os.RemoteException;
85import android.os.ServiceManager;
86import android.os.SystemClock;
87import android.os.SystemProperties;
88import android.os.TokenWatcher;
89import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070090import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070092import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080093import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.util.SparseIntArray;
95import android.view.Display;
96import android.view.Gravity;
Jeff Brown00fa7bd2010-07-02 15:37:36 -070097import android.view.HapticFeedbackConstants;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.view.IApplicationToken;
99import android.view.IOnKeyguardExitResult;
100import android.view.IRotationWatcher;
101import android.view.IWindow;
102import android.view.IWindowManager;
103import android.view.IWindowSession;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700104import android.view.InputChannel;
105import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.view.KeyEvent;
107import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.view.Surface;
109import android.view.SurfaceSession;
110import android.view.View;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700111import android.view.ViewConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.view.ViewTreeObserver;
113import android.view.WindowManager;
114import android.view.WindowManagerImpl;
115import android.view.WindowManagerPolicy;
116import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700117import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import android.view.animation.Animation;
119import android.view.animation.AnimationUtils;
120import android.view.animation.Transformation;
121
122import java.io.BufferedWriter;
123import java.io.File;
124import java.io.FileDescriptor;
125import java.io.IOException;
126import java.io.OutputStream;
127import java.io.OutputStreamWriter;
128import java.io.PrintWriter;
129import java.io.StringWriter;
130import java.net.Socket;
131import java.util.ArrayList;
132import java.util.HashMap;
133import java.util.HashSet;
134import java.util.Iterator;
135import java.util.List;
136
137/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700138public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700139 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 static final String TAG = "WindowManager";
141 static final boolean DEBUG = false;
142 static final boolean DEBUG_FOCUS = false;
143 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800144 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800145 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 static final boolean DEBUG_LAYERS = false;
147 static final boolean DEBUG_INPUT = false;
148 static final boolean DEBUG_INPUT_METHOD = false;
149 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700150 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700152 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_APP_TRANSITIONS = false;
154 static final boolean DEBUG_STARTING_WINDOW = false;
155 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700156 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackbornce73c1e2010-04-12 23:11:38 -0700157 static final boolean DEBUG_FREEZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700159 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700160 static final boolean MEASURE_LATENCY = false;
161 static private LatencyTimer lt;
162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean PROFILE_ORIENTATION = false;
164 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700165 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 /** How much to multiply the policy's type layer, to reserve room
168 * for multiple windows of the same type and Z-ordering adjustment
169 * with TYPE_LAYER_OFFSET. */
170 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
173 * or below others in the same layer. */
174 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 /** How much to increment the layer for each window, to reserve room
177 * for effect surfaces between them.
178 */
179 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 /** The maximum length we will accept for a loaded animation duration:
182 * this is 10 seconds.
183 */
184 static final int MAX_ANIMATION_DURATION = 10*1000;
185
186 /** Amount of time (in milliseconds) to animate the dim surface from one
187 * value to another, when no window animation is driving it.
188 */
189 static final int DEFAULT_DIM_DURATION = 200;
190
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700191 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
192 * compatible windows.
193 */
194 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 /** Adjustment to time to perform a dim, to make it more dramatic.
197 */
198 static final int DIM_DURATION_MULTIPLIER = 6;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700199
200 // Maximum number of milliseconds to wait for input event injection.
201 // FIXME is this value reasonable?
202 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700203
204 // Default input dispatching timeout in nanoseconds.
205 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 static final int UPDATE_FOCUS_NORMAL = 0;
208 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
209 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
210 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700213 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214
215 /**
216 * Condition waited on by {@link #reenableKeyguard} to know the call to
217 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500218 * This is set to true only if mKeyguardTokenWatcher.acquired() has
219 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500221 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222
Jim Miller284b62e2010-06-08 14:27:42 -0700223 private static final int ALLOW_DISABLE_YES = 1;
224 private static final int ALLOW_DISABLE_NO = 0;
225 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
226 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
227
Mike Lockwood983ee092009-11-22 01:42:24 -0500228 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
229 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700231 if (shouldAllowDisableKeyguard()) {
232 mPolicy.enableKeyguard(false);
233 mKeyguardDisabled = true;
234 } else {
235 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 }
238 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700239 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500240 synchronized (mKeyguardTokenWatcher) {
241 mKeyguardDisabled = false;
242 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 }
244 }
245 };
246
Jim Miller284b62e2010-06-08 14:27:42 -0700247 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
248 @Override
249 public void onReceive(Context context, Intent intent) {
250 mPolicy.enableKeyguard(true);
251 synchronized(mKeyguardTokenWatcher) {
252 // lazily evaluate this next time we're asked to disable keyguard
253 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
254 mKeyguardDisabled = false;
255 }
256 }
257 };
258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 final Context mContext;
260
261 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
266
267 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 /**
272 * All currently active sessions with clients.
273 */
274 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 /**
277 * Mapping from an IWindow IBinder to the server's Window object.
278 * This is also used as the lock for all of our state.
279 */
280 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
281
282 /**
283 * Mapping from a token IBinder to a WindowToken object.
284 */
285 final HashMap<IBinder, WindowToken> mTokenMap =
286 new HashMap<IBinder, WindowToken>();
287
288 /**
289 * The same tokens as mTokenMap, stored in a list for efficient iteration
290 * over them.
291 */
292 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 /**
295 * Window tokens that are in the process of exiting, but still
296 * on screen for animations.
297 */
298 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
299
300 /**
301 * Z-ordered (bottom-most first) list of all application tokens, for
302 * controlling the ordering of windows in different applications. This
303 * contains WindowToken objects.
304 */
305 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
306
307 /**
308 * Application tokens that are in the process of exiting, but still
309 * on screen for animations.
310 */
311 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
312
313 /**
314 * List of window tokens that have finished starting their application,
315 * and now need to have the policy remove their windows.
316 */
317 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
318
319 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700320 * This was the app token that was used to retrieve the last enter
321 * animation. It will be used for the next exit animation.
322 */
323 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800324
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700325 /**
326 * These were the layout params used to retrieve the last enter animation.
327 * They will be used for the next exit animation.
328 */
329 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800330
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700331 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 * Z-ordered (bottom-most first) list of all Window objects.
333 */
334 final ArrayList mWindows = new ArrayList();
335
336 /**
337 * Windows that are being resized. Used so we can tell the client about
338 * the resize after closing the transaction in which we resized the
339 * underlying surface.
340 */
341 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
342
343 /**
344 * Windows whose animations have ended and now must be removed.
345 */
346 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
347
348 /**
349 * Windows whose surface should be destroyed.
350 */
351 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
352
353 /**
354 * Windows that have lost input focus and are waiting for the new
355 * focus window to be displayed before they are told about this.
356 */
357 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
358
359 /**
360 * This is set when we have run out of memory, and will either be an empty
361 * list or contain windows that need to be force removed.
362 */
363 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700368 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 Surface mBlurSurface;
370 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 final float[] mTmpFloats = new float[9];
375
376 boolean mSafeMode;
377 boolean mDisplayEnabled = false;
378 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700379 int mInitialDisplayWidth = 0;
380 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 int mRotation = 0;
382 int mRequestedRotation = 0;
383 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700384 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 ArrayList<IRotationWatcher> mRotationWatchers
386 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 boolean mLayoutNeeded = true;
389 boolean mAnimationPending = false;
390 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800391 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 boolean mWindowsFreezingScreen = false;
393 long mFreezeGcPending = 0;
394 int mAppsFreezingScreen = 0;
395
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800396 int mLayoutSeq = 0;
397
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800398 // State while inside of layoutAndPlaceSurfacesLocked().
399 boolean mFocusMayChange;
400
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800401 Configuration mCurConfiguration = new Configuration();
402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 // This is held as long as we have the screen frozen, to give us time to
404 // perform a rotation animation when turning off shows the lock screen which
405 // changes the orientation.
406 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 // State management of app transitions. When we are preparing for a
409 // transition, mNextAppTransition will be the kind of transition to
410 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
411 // mOpeningApps and mClosingApps are the lists of tokens that will be
412 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700413 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700414 String mNextAppTransitionPackage;
415 int mNextAppTransitionEnter;
416 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700418 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 boolean mAppTransitionTimeout = false;
420 boolean mStartingIconInTransition = false;
421 boolean mSkipAppTransitionAnimation = false;
422 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
423 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700424 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
425 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 H mH = new H();
430
431 WindowState mCurrentFocus = null;
432 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 // This just indicates the window the input method is on top of, not
435 // necessarily the window its input is going to.
436 WindowState mInputMethodTarget = null;
437 WindowState mUpcomingInputMethodTarget = null;
438 boolean mInputMethodTargetWaitingAnim;
439 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 WindowState mInputMethodWindow = null;
442 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
443
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700444 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800445
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700446 // If non-null, this is the currently visible window that is associated
447 // with the wallpaper.
448 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700449 // If non-null, we are in the middle of animating from one wallpaper target
450 // to another, and this is the lower one in Z-order.
451 WindowState mLowerWallpaperTarget = null;
452 // If non-null, we are in the middle of animating from one wallpaper target
453 // to another, and this is the higher one in Z-order.
454 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700455 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700456 float mLastWallpaperX = -1;
457 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800458 float mLastWallpaperXStep = -1;
459 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700460 // This is set when we are waiting for a wallpaper to tell us it is done
461 // changing its scroll position.
462 WindowState mWaitingOnWallpaper;
463 // The last time we had a timeout when waiting for a wallpaper.
464 long mLastWallpaperTimeoutTime;
465 // We give a wallpaper up to 150ms to finish scrolling.
466 static final long WALLPAPER_TIMEOUT = 150;
467 // Time we wait after a timeout before trying to wait again.
468 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 AppWindowToken mFocusedApp = null;
471
472 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 float mWindowAnimationScale = 1.0f;
475 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700476
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700477 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478
479 // Who is holding the screen on.
480 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700481 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700482
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700483 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 /**
486 * Whether the UI is currently running in touch mode (not showing
487 * navigational focus because the user is directly pressing the screen).
488 */
489 boolean mInTouchMode = false;
490
491 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700492 private ArrayList<WindowChangeListener> mWindowChangeListeners =
493 new ArrayList<WindowChangeListener>();
494 private boolean mWindowsChanged = false;
495
496 public interface WindowChangeListener {
497 public void windowsChanged();
498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499
Dianne Hackbornc485a602009-03-24 22:39:49 -0700500 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700501 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700502
503 // The frame use to limit the size of the app running in compatibility mode.
504 Rect mCompatibleScreenFrame = new Rect();
505 // The surface used to fill the outer rim of the app running in compatibility mode.
506 Surface mBackgroundFillerSurface = null;
507 boolean mBackgroundFillerShown = false;
508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 public static WindowManagerService main(Context context,
510 PowerManagerService pm, boolean haveInputMethods) {
511 WMThread thr = new WMThread(context, pm, haveInputMethods);
512 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 synchronized (thr) {
515 while (thr.mService == null) {
516 try {
517 thr.wait();
518 } catch (InterruptedException e) {
519 }
520 }
521 }
Romain Guy06882f82009-06-10 13:36:04 -0700522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 return thr.mService;
524 }
Romain Guy06882f82009-06-10 13:36:04 -0700525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 static class WMThread extends Thread {
527 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 private final Context mContext;
530 private final PowerManagerService mPM;
531 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 public WMThread(Context context, PowerManagerService pm,
534 boolean haveInputMethods) {
535 super("WindowManager");
536 mContext = context;
537 mPM = pm;
538 mHaveInputMethods = haveInputMethods;
539 }
Romain Guy06882f82009-06-10 13:36:04 -0700540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 public void run() {
542 Looper.prepare();
543 WindowManagerService s = new WindowManagerService(mContext, mPM,
544 mHaveInputMethods);
545 android.os.Process.setThreadPriority(
546 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700547 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 synchronized (this) {
550 mService = s;
551 notifyAll();
552 }
Romain Guy06882f82009-06-10 13:36:04 -0700553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 Looper.loop();
555 }
556 }
557
558 static class PolicyThread extends Thread {
559 private final WindowManagerPolicy mPolicy;
560 private final WindowManagerService mService;
561 private final Context mContext;
562 private final PowerManagerService mPM;
563 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 public PolicyThread(WindowManagerPolicy policy,
566 WindowManagerService service, Context context,
567 PowerManagerService pm) {
568 super("WindowManagerPolicy");
569 mPolicy = policy;
570 mService = service;
571 mContext = context;
572 mPM = pm;
573 }
Romain Guy06882f82009-06-10 13:36:04 -0700574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 public void run() {
576 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800577 WindowManagerPolicyThread.set(this, Looper.myLooper());
578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800580 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 android.os.Process.setThreadPriority(
582 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700583 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 synchronized (this) {
587 mRunning = true;
588 notifyAll();
589 }
Romain Guy06882f82009-06-10 13:36:04 -0700590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 Looper.loop();
592 }
593 }
594
595 private WindowManagerService(Context context, PowerManagerService pm,
596 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700597 if (MEASURE_LATENCY) {
598 lt = new LatencyTimer(100, 1000);
599 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 mContext = context;
602 mHaveInputMethods = haveInputMethods;
603 mLimitedAlphaCompositing = context.getResources().getBoolean(
604 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 mPowerManager = pm;
607 mPowerManager.setPolicy(mPolicy);
608 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
609 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
610 "SCREEN_FROZEN");
611 mScreenFrozenLock.setReferenceCounted(false);
612
613 mActivityManager = ActivityManagerNative.getDefault();
614 mBatteryStats = BatteryStatsService.getService();
615
616 // Get persisted window scale setting
617 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
618 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
619 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
620 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700621
Jim Miller284b62e2010-06-08 14:27:42 -0700622 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
623 IntentFilter filter = new IntentFilter();
624 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
625 mContext.registerReceiver(mBroadcastReceiver, filter);
626
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700627 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
628 "KEEP_SCREEN_ON_FLAG");
629 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700631 mInputManager = new InputManager(context, this, pmc, mPowerManager);
Romain Guy06882f82009-06-10 13:36:04 -0700632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
634 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 synchronized (thr) {
637 while (!thr.mRunning) {
638 try {
639 thr.wait();
640 } catch (InterruptedException e) {
641 }
642 }
643 }
Romain Guy06882f82009-06-10 13:36:04 -0700644
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700645 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 // Add ourself to the Watchdog monitors.
648 Watchdog.getInstance().addMonitor(this);
649 }
650
651 @Override
652 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
653 throws RemoteException {
654 try {
655 return super.onTransact(code, data, reply, flags);
656 } catch (RuntimeException e) {
657 // The window manager only throws security exceptions, so let's
658 // log all others.
659 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800660 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 }
662 throw e;
663 }
664 }
665
666 private void placeWindowAfter(Object pos, WindowState window) {
667 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800668 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 TAG, "Adding window " + window + " at "
670 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
671 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700672 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 }
674
675 private void placeWindowBefore(Object pos, WindowState window) {
676 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800677 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 TAG, "Adding window " + window + " at "
679 + i + " of " + mWindows.size() + " (before " + pos + ")");
680 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700681 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682 }
683
684 //This method finds out the index of a window that has the same app token as
685 //win. used for z ordering the windows in mWindows
686 private int findIdxBasedOnAppTokens(WindowState win) {
687 //use a local variable to cache mWindows
688 ArrayList localmWindows = mWindows;
689 int jmax = localmWindows.size();
690 if(jmax == 0) {
691 return -1;
692 }
693 for(int j = (jmax-1); j >= 0; j--) {
694 WindowState wentry = (WindowState)localmWindows.get(j);
695 if(wentry.mAppToken == win.mAppToken) {
696 return j;
697 }
698 }
699 return -1;
700 }
Romain Guy06882f82009-06-10 13:36:04 -0700701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
703 final IWindow client = win.mClient;
704 final WindowToken token = win.mToken;
705 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 final int N = localmWindows.size();
708 final WindowState attached = win.mAttachedWindow;
709 int i;
710 if (attached == null) {
711 int tokenWindowsPos = token.windows.size();
712 if (token.appWindowToken != null) {
713 int index = tokenWindowsPos-1;
714 if (index >= 0) {
715 // If this application has existing windows, we
716 // simply place the new window on top of them... but
717 // keep the starting window on top.
718 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
719 // Base windows go behind everything else.
720 placeWindowBefore(token.windows.get(0), win);
721 tokenWindowsPos = 0;
722 } else {
723 AppWindowToken atoken = win.mAppToken;
724 if (atoken != null &&
725 token.windows.get(index) == atoken.startingWindow) {
726 placeWindowBefore(token.windows.get(index), win);
727 tokenWindowsPos--;
728 } else {
729 int newIdx = findIdxBasedOnAppTokens(win);
730 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700731 //there is a window above this one associated with the same
732 //apptoken note that the window could be a floating window
733 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800735 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700736 TAG, "Adding window " + win + " at "
737 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700739 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -0700740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 }
742 }
743 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800744 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 TAG, "Figuring out where to add app window "
746 + client.asBinder() + " (token=" + token + ")");
747 // Figure out where the window should go, based on the
748 // order of applications.
749 final int NA = mAppTokens.size();
750 Object pos = null;
751 for (i=NA-1; i>=0; i--) {
752 AppWindowToken t = mAppTokens.get(i);
753 if (t == token) {
754 i--;
755 break;
756 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800757
Dianne Hackborna8f60182009-09-01 19:01:50 -0700758 // We haven't reached the token yet; if this token
759 // is not going to the bottom and has windows, we can
760 // use it as an anchor for when we do reach the token.
761 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 pos = t.windows.get(0);
763 }
764 }
765 // We now know the index into the apps. If we found
766 // an app window above, that gives us the position; else
767 // we need to look some more.
768 if (pos != null) {
769 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700770 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 mTokenMap.get(((WindowState)pos).mClient.asBinder());
772 if (atoken != null) {
773 final int NC = atoken.windows.size();
774 if (NC > 0) {
775 WindowState bottom = atoken.windows.get(0);
776 if (bottom.mSubLayer < 0) {
777 pos = bottom;
778 }
779 }
780 }
781 placeWindowBefore(pos, win);
782 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700783 // Continue looking down until we find the first
784 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 while (i >= 0) {
786 AppWindowToken t = mAppTokens.get(i);
787 final int NW = t.windows.size();
788 if (NW > 0) {
789 pos = t.windows.get(NW-1);
790 break;
791 }
792 i--;
793 }
794 if (pos != null) {
795 // Move in front of any windows attached to this
796 // one.
797 WindowToken atoken =
798 mTokenMap.get(((WindowState)pos).mClient.asBinder());
799 if (atoken != null) {
800 final int NC = atoken.windows.size();
801 if (NC > 0) {
802 WindowState top = atoken.windows.get(NC-1);
803 if (top.mSubLayer >= 0) {
804 pos = top;
805 }
806 }
807 }
808 placeWindowAfter(pos, win);
809 } else {
810 // Just search for the start of this layer.
811 final int myLayer = win.mBaseLayer;
812 for (i=0; i<N; i++) {
813 WindowState w = (WindowState)localmWindows.get(i);
814 if (w.mBaseLayer > myLayer) {
815 break;
816 }
817 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800818 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700819 TAG, "Adding window " + win + " at "
820 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700822 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 }
824 }
825 }
826 } else {
827 // Figure out where window should go, based on layer.
828 final int myLayer = win.mBaseLayer;
829 for (i=N-1; i>=0; i--) {
830 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
831 i++;
832 break;
833 }
834 }
835 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800836 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700837 TAG, "Adding window " + win + " at "
838 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700840 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 }
842 if (addToToken) {
843 token.windows.add(tokenWindowsPos, win);
844 }
845
846 } else {
847 // Figure out this window's ordering relative to the window
848 // it is attached to.
849 final int NA = token.windows.size();
850 final int sublayer = win.mSubLayer;
851 int largestSublayer = Integer.MIN_VALUE;
852 WindowState windowWithLargestSublayer = null;
853 for (i=0; i<NA; i++) {
854 WindowState w = token.windows.get(i);
855 final int wSublayer = w.mSubLayer;
856 if (wSublayer >= largestSublayer) {
857 largestSublayer = wSublayer;
858 windowWithLargestSublayer = w;
859 }
860 if (sublayer < 0) {
861 // For negative sublayers, we go below all windows
862 // in the same sublayer.
863 if (wSublayer >= sublayer) {
864 if (addToToken) {
865 token.windows.add(i, win);
866 }
867 placeWindowBefore(
868 wSublayer >= 0 ? attached : w, win);
869 break;
870 }
871 } else {
872 // For positive sublayers, we go above all windows
873 // in the same sublayer.
874 if (wSublayer > sublayer) {
875 if (addToToken) {
876 token.windows.add(i, win);
877 }
878 placeWindowBefore(w, win);
879 break;
880 }
881 }
882 }
883 if (i >= NA) {
884 if (addToToken) {
885 token.windows.add(win);
886 }
887 if (sublayer < 0) {
888 placeWindowBefore(attached, win);
889 } else {
890 placeWindowAfter(largestSublayer >= 0
891 ? windowWithLargestSublayer
892 : attached,
893 win);
894 }
895 }
896 }
Romain Guy06882f82009-06-10 13:36:04 -0700897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 if (win.mAppToken != null && addToToken) {
899 win.mAppToken.allAppWindows.add(win);
900 }
901 }
Romain Guy06882f82009-06-10 13:36:04 -0700902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 static boolean canBeImeTarget(WindowState w) {
904 final int fl = w.mAttrs.flags
905 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
906 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
907 return w.isVisibleOrAdding();
908 }
909 return false;
910 }
Romain Guy06882f82009-06-10 13:36:04 -0700911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
913 final ArrayList localmWindows = mWindows;
914 final int N = localmWindows.size();
915 WindowState w = null;
916 int i = N;
917 while (i > 0) {
918 i--;
919 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700920
Joe Onorato8a9b2202010-02-26 18:56:32 -0800921 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 // + Integer.toHexString(w.mAttrs.flags));
923 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800924 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 // Yet more tricksyness! If this window is a "starting"
927 // window, we do actually want to be on top of it, but
928 // it is not -really- where input will go. So if the caller
929 // is not actually looking to move the IME, look down below
930 // for a real window to target...
931 if (!willMove
932 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
933 && i > 0) {
934 WindowState wb = (WindowState)localmWindows.get(i-1);
935 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
936 i--;
937 w = wb;
938 }
939 }
940 break;
941 }
942 }
Romain Guy06882f82009-06-10 13:36:04 -0700943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700945
Joe Onorato8a9b2202010-02-26 18:56:32 -0800946 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 if (willMove && w != null) {
950 final WindowState curTarget = mInputMethodTarget;
951 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 // Now some fun for dealing with window animations that
954 // modify the Z order. We need to look at all windows below
955 // the current target that are in this app, finding the highest
956 // visible one in layering.
957 AppWindowToken token = curTarget.mAppToken;
958 WindowState highestTarget = null;
959 int highestPos = 0;
960 if (token.animating || token.animation != null) {
961 int pos = 0;
962 pos = localmWindows.indexOf(curTarget);
963 while (pos >= 0) {
964 WindowState win = (WindowState)localmWindows.get(pos);
965 if (win.mAppToken != token) {
966 break;
967 }
968 if (!win.mRemoved) {
969 if (highestTarget == null || win.mAnimLayer >
970 highestTarget.mAnimLayer) {
971 highestTarget = win;
972 highestPos = pos;
973 }
974 }
975 pos--;
976 }
977 }
Romain Guy06882f82009-06-10 13:36:04 -0700978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800980 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 + mNextAppTransition + " " + highestTarget
982 + " animating=" + highestTarget.isAnimating()
983 + " layer=" + highestTarget.mAnimLayer
984 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -0700985
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700986 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 // If we are currently setting up for an animation,
988 // hold everything until we can find out what will happen.
989 mInputMethodTargetWaitingAnim = true;
990 mInputMethodTarget = highestTarget;
991 return highestPos + 1;
992 } else if (highestTarget.isAnimating() &&
993 highestTarget.mAnimLayer > w.mAnimLayer) {
994 // If the window we are currently targeting is involved
995 // with an animation, and it is on top of the next target
996 // we will be over, then hold off on moving until
997 // that is done.
998 mInputMethodTarget = highestTarget;
999 return highestPos + 1;
1000 }
1001 }
1002 }
1003 }
Romain Guy06882f82009-06-10 13:36:04 -07001004
Joe Onorato8a9b2202010-02-26 18:56:32 -08001005 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 if (w != null) {
1007 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001008 if (DEBUG_INPUT_METHOD) {
1009 RuntimeException e = null;
1010 if (!HIDE_STACK_CRAWLS) {
1011 e = new RuntimeException();
1012 e.fillInStackTrace();
1013 }
1014 Slog.w(TAG, "Moving IM target from "
1015 + mInputMethodTarget + " to " + w, e);
1016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 mInputMethodTarget = w;
1018 if (w.mAppToken != null) {
1019 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1020 } else {
1021 setInputMethodAnimLayerAdjustment(0);
1022 }
1023 }
1024 return i+1;
1025 }
1026 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001027 if (DEBUG_INPUT_METHOD) {
1028 RuntimeException e = null;
1029 if (!HIDE_STACK_CRAWLS) {
1030 e = new RuntimeException();
1031 e.fillInStackTrace();
1032 }
1033 Slog.w(TAG, "Moving IM target from "
1034 + mInputMethodTarget + " to null", e);
1035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 mInputMethodTarget = null;
1037 setInputMethodAnimLayerAdjustment(0);
1038 }
1039 return -1;
1040 }
Romain Guy06882f82009-06-10 13:36:04 -07001041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 void addInputMethodWindowToListLocked(WindowState win) {
1043 int pos = findDesiredInputMethodWindowIndexLocked(true);
1044 if (pos >= 0) {
1045 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001046 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001047 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001049 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 moveInputMethodDialogsLocked(pos+1);
1051 return;
1052 }
1053 win.mTargetAppToken = null;
1054 addWindowToListInOrderLocked(win, true);
1055 moveInputMethodDialogsLocked(pos);
1056 }
Romain Guy06882f82009-06-10 13:36:04 -07001057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001059 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 mInputMethodAnimLayerAdjustment = adj;
1061 WindowState imw = mInputMethodWindow;
1062 if (imw != null) {
1063 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001064 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 + " anim layer: " + imw.mAnimLayer);
1066 int wi = imw.mChildWindows.size();
1067 while (wi > 0) {
1068 wi--;
1069 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1070 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001071 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 + " anim layer: " + cw.mAnimLayer);
1073 }
1074 }
1075 int di = mInputMethodDialogs.size();
1076 while (di > 0) {
1077 di --;
1078 imw = mInputMethodDialogs.get(di);
1079 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001080 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 + " anim layer: " + imw.mAnimLayer);
1082 }
1083 }
Romain Guy06882f82009-06-10 13:36:04 -07001084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1086 int wpos = mWindows.indexOf(win);
1087 if (wpos >= 0) {
1088 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001089 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001091 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 int NC = win.mChildWindows.size();
1093 while (NC > 0) {
1094 NC--;
1095 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1096 int cpos = mWindows.indexOf(cw);
1097 if (cpos >= 0) {
1098 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001099 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001100 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 mWindows.remove(cpos);
1102 }
1103 }
1104 }
1105 return interestingPos;
1106 }
Romain Guy06882f82009-06-10 13:36:04 -07001107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 private void reAddWindowToListInOrderLocked(WindowState win) {
1109 addWindowToListInOrderLocked(win, false);
1110 // This is a hack to get all of the child windows added as well
1111 // at the right position. Child windows should be rare and
1112 // this case should be rare, so it shouldn't be that big a deal.
1113 int wpos = mWindows.indexOf(win);
1114 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001115 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001116 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001118 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 reAddWindowLocked(wpos, win);
1120 }
1121 }
Romain Guy06882f82009-06-10 13:36:04 -07001122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 void logWindowList(String prefix) {
1124 int N = mWindows.size();
1125 while (N > 0) {
1126 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001127 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 }
1129 }
Romain Guy06882f82009-06-10 13:36:04 -07001130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 void moveInputMethodDialogsLocked(int pos) {
1132 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001135 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 for (int i=0; i<N; i++) {
1137 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1138 }
1139 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001140 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 logWindowList(" ");
1142 }
Romain Guy06882f82009-06-10 13:36:04 -07001143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 if (pos >= 0) {
1145 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1146 if (pos < mWindows.size()) {
1147 WindowState wp = (WindowState)mWindows.get(pos);
1148 if (wp == mInputMethodWindow) {
1149 pos++;
1150 }
1151 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001152 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 for (int i=0; i<N; i++) {
1154 WindowState win = dialogs.get(i);
1155 win.mTargetAppToken = targetAppToken;
1156 pos = reAddWindowLocked(pos, win);
1157 }
1158 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001159 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 logWindowList(" ");
1161 }
1162 return;
1163 }
1164 for (int i=0; i<N; i++) {
1165 WindowState win = dialogs.get(i);
1166 win.mTargetAppToken = null;
1167 reAddWindowToListInOrderLocked(win);
1168 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001169 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 logWindowList(" ");
1171 }
1172 }
1173 }
Romain Guy06882f82009-06-10 13:36:04 -07001174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1176 final WindowState imWin = mInputMethodWindow;
1177 final int DN = mInputMethodDialogs.size();
1178 if (imWin == null && DN == 0) {
1179 return false;
1180 }
Romain Guy06882f82009-06-10 13:36:04 -07001181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1183 if (imPos >= 0) {
1184 // In this case, the input method windows are to be placed
1185 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 // First check to see if the input method windows are already
1188 // located here, and contiguous.
1189 final int N = mWindows.size();
1190 WindowState firstImWin = imPos < N
1191 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 // Figure out the actual input method window that should be
1194 // at the bottom of their stack.
1195 WindowState baseImWin = imWin != null
1196 ? imWin : mInputMethodDialogs.get(0);
1197 if (baseImWin.mChildWindows.size() > 0) {
1198 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1199 if (cw.mSubLayer < 0) baseImWin = cw;
1200 }
Romain Guy06882f82009-06-10 13:36:04 -07001201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 if (firstImWin == baseImWin) {
1203 // The windows haven't moved... but are they still contiguous?
1204 // First find the top IM window.
1205 int pos = imPos+1;
1206 while (pos < N) {
1207 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1208 break;
1209 }
1210 pos++;
1211 }
1212 pos++;
1213 // Now there should be no more input method windows above.
1214 while (pos < N) {
1215 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1216 break;
1217 }
1218 pos++;
1219 }
1220 if (pos >= N) {
1221 // All is good!
1222 return false;
1223 }
1224 }
Romain Guy06882f82009-06-10 13:36:04 -07001225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 if (imWin != null) {
1227 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001228 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 logWindowList(" ");
1230 }
1231 imPos = tmpRemoveWindowLocked(imPos, imWin);
1232 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001233 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 logWindowList(" ");
1235 }
1236 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1237 reAddWindowLocked(imPos, imWin);
1238 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001239 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 logWindowList(" ");
1241 }
1242 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1243 } else {
1244 moveInputMethodDialogsLocked(imPos);
1245 }
Romain Guy06882f82009-06-10 13:36:04 -07001246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 } else {
1248 // In this case, the input method windows go in a fixed layer,
1249 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001252 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 tmpRemoveWindowLocked(0, imWin);
1254 imWin.mTargetAppToken = null;
1255 reAddWindowToListInOrderLocked(imWin);
1256 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001257 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 logWindowList(" ");
1259 }
1260 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1261 } else {
1262 moveInputMethodDialogsLocked(-1);;
1263 }
Romain Guy06882f82009-06-10 13:36:04 -07001264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 }
Romain Guy06882f82009-06-10 13:36:04 -07001266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 if (needAssignLayers) {
1268 assignLayersLocked();
1269 }
Romain Guy06882f82009-06-10 13:36:04 -07001270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 return true;
1272 }
Romain Guy06882f82009-06-10 13:36:04 -07001273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 void adjustInputMethodDialogsLocked() {
1275 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1276 }
Romain Guy06882f82009-06-10 13:36:04 -07001277
Dianne Hackborn25994b42009-09-04 14:21:19 -07001278 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001279 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001280 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1281 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1282 ? wallpaperTarget.mAppToken.animation : null)
1283 + " upper=" + mUpperWallpaperTarget
1284 + " lower=" + mLowerWallpaperTarget);
1285 return (wallpaperTarget != null
1286 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1287 && wallpaperTarget.mAppToken.animation != null)))
1288 || mUpperWallpaperTarget != null
1289 || mLowerWallpaperTarget != null;
1290 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001291
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001292 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1293 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001294
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001295 int adjustWallpaperWindowsLocked() {
1296 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001297
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001298 final int dw = mDisplay.getWidth();
1299 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001300
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001301 // First find top-most window that has asked to be on top of the
1302 // wallpaper; all wallpapers go behind it.
1303 final ArrayList localmWindows = mWindows;
1304 int N = localmWindows.size();
1305 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001306 WindowState foundW = null;
1307 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001308 WindowState topCurW = null;
1309 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001310 int i = N;
1311 while (i > 0) {
1312 i--;
1313 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001314 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1315 if (topCurW == null) {
1316 topCurW = w;
1317 topCurI = i;
1318 }
1319 continue;
1320 }
1321 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001322 if (w.mAppToken != null) {
1323 // If this window's app token is hidden and not animating,
1324 // it is of no interest to us.
1325 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001326 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001327 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001328 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001329 continue;
1330 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001331 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001332 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001333 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1334 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001335 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001336 && (mWallpaperTarget == w
1337 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001338 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001339 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001340 foundW = w;
1341 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001342 if (w == mWallpaperTarget && ((w.mAppToken != null
1343 && w.mAppToken.animation != null)
1344 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001345 // The current wallpaper target is animating, so we'll
1346 // look behind it for another possible target and figure
1347 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001348 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001349 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001350 continue;
1351 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001352 break;
1353 }
1354 }
1355
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001356 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001357 // If we are currently waiting for an app transition, and either
1358 // the current target or the next target are involved with it,
1359 // then hold off on doing anything with the wallpaper.
1360 // Note that we are checking here for just whether the target
1361 // is part of an app token... which is potentially overly aggressive
1362 // (the app token may not be involved in the transition), but good
1363 // enough (we'll just wait until whatever transition is pending
1364 // executes).
1365 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001366 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001367 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001368 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001369 }
1370 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001371 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001372 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001373 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001374 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001375 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001376
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001377 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001378 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001379 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001380 + " oldTarget: " + mWallpaperTarget);
1381 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001382
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001383 mLowerWallpaperTarget = null;
1384 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001385
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001386 WindowState oldW = mWallpaperTarget;
1387 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001388
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001389 // Now what is happening... if the current and new targets are
1390 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001391 if (foundW != null && oldW != null) {
1392 boolean oldAnim = oldW.mAnimation != null
1393 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1394 boolean foundAnim = foundW.mAnimation != null
1395 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001396 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001397 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001398 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001399 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001400 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001401 int oldI = localmWindows.indexOf(oldW);
1402 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001403 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001404 }
1405 if (oldI >= 0) {
1406 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001407 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001408 + "=" + oldW + "; new#" + foundI
1409 + "=" + foundW);
1410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001411
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001412 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001413 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001414 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001416 }
1417 mWallpaperTarget = oldW;
1418 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001419
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001420 // Now set the upper and lower wallpaper targets
1421 // correctly, and make sure that we are positioning
1422 // the wallpaper below the lower.
1423 if (foundI > oldI) {
1424 // The new target is on top of the old one.
1425 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001426 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001427 }
1428 mUpperWallpaperTarget = foundW;
1429 mLowerWallpaperTarget = oldW;
1430 foundW = oldW;
1431 foundI = oldI;
1432 } else {
1433 // The new target is below the old one.
1434 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001435 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001436 }
1437 mUpperWallpaperTarget = oldW;
1438 mLowerWallpaperTarget = foundW;
1439 }
1440 }
1441 }
1442 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001443
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001444 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001445 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001446 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1447 || (mLowerWallpaperTarget.mAppToken != null
1448 && mLowerWallpaperTarget.mAppToken.animation != null);
1449 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1450 || (mUpperWallpaperTarget.mAppToken != null
1451 && mUpperWallpaperTarget.mAppToken.animation != null);
1452 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001453 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001454 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001455 }
1456 mLowerWallpaperTarget = null;
1457 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001458 }
1459 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001460
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001461 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001462 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001463 // The window is visible to the compositor... but is it visible
1464 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001465 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001466 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001467
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001468 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001469 // its layer adjustment. Only do this if we are not transfering
1470 // between two wallpaper targets.
1471 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001472 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001473 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001474
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001475 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1476 * TYPE_LAYER_MULTIPLIER
1477 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001478
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001479 // Now w is the window we are supposed to be behind... but we
1480 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001481 // AND any starting window associated with it, AND below the
1482 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001483 while (foundI > 0) {
1484 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001485 if (wb.mBaseLayer < maxLayer &&
1486 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001487 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001488 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001489 // This window is not related to the previous one in any
1490 // interesting way, so stop here.
1491 break;
1492 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001493 foundW = wb;
1494 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001495 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001496 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001497 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001498 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001499
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001500 if (foundW == null && topCurW != null) {
1501 // There is no wallpaper target, so it goes at the bottom.
1502 // We will assume it is the same place as last time, if known.
1503 foundW = topCurW;
1504 foundI = topCurI+1;
1505 } else {
1506 // Okay i is the position immediately above the wallpaper. Look at
1507 // what is below it for later.
1508 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1509 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001510
Dianne Hackborn284ac932009-08-28 10:34:25 -07001511 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001512 if (mWallpaperTarget.mWallpaperX >= 0) {
1513 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001514 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001515 }
1516 if (mWallpaperTarget.mWallpaperY >= 0) {
1517 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001518 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001519 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001520 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001521
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001522 // Start stepping backwards from here, ensuring that our wallpaper windows
1523 // are correctly placed.
1524 int curTokenIndex = mWallpaperTokens.size();
1525 while (curTokenIndex > 0) {
1526 curTokenIndex--;
1527 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001528 if (token.hidden == visible) {
1529 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1530 token.hidden = !visible;
1531 // Need to do a layout to ensure the wallpaper now has the
1532 // correct size.
1533 mLayoutNeeded = true;
1534 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001535
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001536 int curWallpaperIndex = token.windows.size();
1537 while (curWallpaperIndex > 0) {
1538 curWallpaperIndex--;
1539 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001540
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001541 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001542 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001543 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001544
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001545 // First, make sure the client has the current visibility
1546 // state.
1547 if (wallpaper.mWallpaperVisible != visible) {
1548 wallpaper.mWallpaperVisible = visible;
1549 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001551 "Setting visibility of wallpaper " + wallpaper
1552 + ": " + visible);
1553 wallpaper.mClient.dispatchAppVisibility(visible);
1554 } catch (RemoteException e) {
1555 }
1556 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001557
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001558 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001559 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001560 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001561
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001562 // First, if this window is at the current index, then all
1563 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001564 if (wallpaper == foundW) {
1565 foundI--;
1566 foundW = foundI > 0
1567 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001568 continue;
1569 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001571 // The window didn't match... the current wallpaper window,
1572 // wherever it is, is in the wrong place, so make sure it is
1573 // not in the list.
1574 int oldIndex = localmWindows.indexOf(wallpaper);
1575 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001576 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001577 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001578 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001579 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001580 if (oldIndex < foundI) {
1581 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001582 }
1583 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001584
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001585 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001586 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001587 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001588 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001589
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001590 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001591 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001592 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001593 }
1594 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001595
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001596 return changed;
1597 }
1598
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001599 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001600 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001601 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001602 mWallpaperAnimLayerAdjustment = adj;
1603 int curTokenIndex = mWallpaperTokens.size();
1604 while (curTokenIndex > 0) {
1605 curTokenIndex--;
1606 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1607 int curWallpaperIndex = token.windows.size();
1608 while (curWallpaperIndex > 0) {
1609 curWallpaperIndex--;
1610 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1611 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001612 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001613 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001614 }
1615 }
1616 }
1617
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001618 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1619 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001620 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001621 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001622 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001623 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001624 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1625 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1626 changed = wallpaperWin.mXOffset != offset;
1627 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001628 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001629 + wallpaperWin + " x: " + offset);
1630 wallpaperWin.mXOffset = offset;
1631 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001632 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001633 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001634 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001635 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001636 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001637
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001638 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001639 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001640 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1641 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1642 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001643 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001644 + wallpaperWin + " y: " + offset);
1645 changed = true;
1646 wallpaperWin.mYOffset = offset;
1647 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001648 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001649 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001650 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001651 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001652 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001653
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001654 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001655 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001656 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001657 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1658 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001659 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001660 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001661 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001662 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001663 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1664 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001665 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001666 if (mWaitingOnWallpaper != null) {
1667 long start = SystemClock.uptimeMillis();
1668 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1669 < start) {
1670 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001671 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001672 "Waiting for offset complete...");
1673 mWindowMap.wait(WALLPAPER_TIMEOUT);
1674 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001675 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001677 if ((start+WALLPAPER_TIMEOUT)
1678 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001679 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001680 + wallpaperWin);
1681 mLastWallpaperTimeoutTime = start;
1682 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001683 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001684 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001685 }
1686 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001687 } catch (RemoteException e) {
1688 }
1689 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001690
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001691 return changed;
1692 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001693
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001694 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001695 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001696 if (mWaitingOnWallpaper != null &&
1697 mWaitingOnWallpaper.mClient.asBinder() == window) {
1698 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001699 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001700 }
1701 }
1702 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001703
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001704 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001705 final int dw = mDisplay.getWidth();
1706 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001707
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001708 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001709
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001710 WindowState target = mWallpaperTarget;
1711 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001712 if (target.mWallpaperX >= 0) {
1713 mLastWallpaperX = target.mWallpaperX;
1714 } else if (changingTarget.mWallpaperX >= 0) {
1715 mLastWallpaperX = changingTarget.mWallpaperX;
1716 }
1717 if (target.mWallpaperY >= 0) {
1718 mLastWallpaperY = target.mWallpaperY;
1719 } else if (changingTarget.mWallpaperY >= 0) {
1720 mLastWallpaperY = changingTarget.mWallpaperY;
1721 }
1722 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001723
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001724 int curTokenIndex = mWallpaperTokens.size();
1725 while (curTokenIndex > 0) {
1726 curTokenIndex--;
1727 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1728 int curWallpaperIndex = token.windows.size();
1729 while (curWallpaperIndex > 0) {
1730 curWallpaperIndex--;
1731 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1732 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1733 wallpaper.computeShownFrameLocked();
1734 changed = true;
1735 // We only want to be synchronous with one wallpaper.
1736 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001737 }
1738 }
1739 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001740
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001741 return changed;
1742 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001743
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001744 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001745 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001746 final int dw = mDisplay.getWidth();
1747 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001748
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001749 int curTokenIndex = mWallpaperTokens.size();
1750 while (curTokenIndex > 0) {
1751 curTokenIndex--;
1752 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001753 if (token.hidden == visible) {
1754 token.hidden = !visible;
1755 // Need to do a layout to ensure the wallpaper now has the
1756 // correct size.
1757 mLayoutNeeded = true;
1758 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001759
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001760 int curWallpaperIndex = token.windows.size();
1761 while (curWallpaperIndex > 0) {
1762 curWallpaperIndex--;
1763 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1764 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001765 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001766 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001767
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001768 if (wallpaper.mWallpaperVisible != visible) {
1769 wallpaper.mWallpaperVisible = visible;
1770 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001771 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001772 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001773 + ": " + visible);
1774 wallpaper.mClient.dispatchAppVisibility(visible);
1775 } catch (RemoteException e) {
1776 }
1777 }
1778 }
1779 }
1780 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 public int addWindow(Session session, IWindow client,
1783 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001784 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 int res = mPolicy.checkAddPermission(attrs);
1786 if (res != WindowManagerImpl.ADD_OKAY) {
1787 return res;
1788 }
Romain Guy06882f82009-06-10 13:36:04 -07001789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 boolean reportNewConfig = false;
1791 WindowState attachedWindow = null;
1792 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 synchronized(mWindowMap) {
1795 // Instantiating a Display requires talking with the simulator,
1796 // so don't do it until we know the system is mostly up and
1797 // running.
1798 if (mDisplay == null) {
1799 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1800 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001801 mInitialDisplayWidth = mDisplay.getWidth();
1802 mInitialDisplayHeight = mDisplay.getHeight();
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001803 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 reportNewConfig = true;
1805 }
Romain Guy06882f82009-06-10 13:36:04 -07001806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001808 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1810 }
1811
1812 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001813 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001815 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 + attrs.token + ". Aborting.");
1817 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1818 }
1819 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1820 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001821 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 + attrs.token + ". Aborting.");
1823 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1824 }
1825 }
1826
1827 boolean addToken = false;
1828 WindowToken token = mTokenMap.get(attrs.token);
1829 if (token == null) {
1830 if (attrs.type >= FIRST_APPLICATION_WINDOW
1831 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001832 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 + attrs.token + ". Aborting.");
1834 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1835 }
1836 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001837 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 + attrs.token + ". Aborting.");
1839 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1840 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001841 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001842 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001843 + attrs.token + ". Aborting.");
1844 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 token = new WindowToken(attrs.token, -1, false);
1847 addToken = true;
1848 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1849 && attrs.type <= LAST_APPLICATION_WINDOW) {
1850 AppWindowToken atoken = token.appWindowToken;
1851 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001852 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 + token + ". Aborting.");
1854 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1855 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001856 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 + token + ". Aborting.");
1858 return WindowManagerImpl.ADD_APP_EXITING;
1859 }
1860 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1861 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001862 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1864 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1865 }
1866 } else if (attrs.type == TYPE_INPUT_METHOD) {
1867 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001868 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 + attrs.token + ". Aborting.");
1870 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1871 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001872 } else if (attrs.type == TYPE_WALLPAPER) {
1873 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001874 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001875 + attrs.token + ". Aborting.");
1876 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 }
1879
1880 win = new WindowState(session, client, token,
1881 attachedWindow, attrs, viewVisibility);
1882 if (win.mDeathRecipient == null) {
1883 // Client has apparently died, so there is no reason to
1884 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001885 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 + " that is dead, aborting.");
1887 return WindowManagerImpl.ADD_APP_EXITING;
1888 }
1889
1890 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 res = mPolicy.prepareAddWindowLw(win, attrs);
1893 if (res != WindowManagerImpl.ADD_OKAY) {
1894 return res;
1895 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001896
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001897 if (outInputChannel != null) {
1898 String name = win.makeInputChannelName();
1899 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
1900 win.mInputChannel = inputChannels[0];
1901 inputChannels[1].transferToBinderOutParameter(outInputChannel);
1902
1903 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905
1906 // From now on, no exceptions or errors allowed!
1907
1908 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07001909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07001911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 if (addToken) {
1913 mTokenMap.put(attrs.token, token);
1914 mTokenList.add(token);
1915 }
1916 win.attach();
1917 mWindowMap.put(client.asBinder(), win);
1918
1919 if (attrs.type == TYPE_APPLICATION_STARTING &&
1920 token.appWindowToken != null) {
1921 token.appWindowToken.startingWindow = win;
1922 }
1923
1924 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07001925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 if (attrs.type == TYPE_INPUT_METHOD) {
1927 mInputMethodWindow = win;
1928 addInputMethodWindowToListLocked(win);
1929 imMayMove = false;
1930 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
1931 mInputMethodDialogs.add(win);
1932 addWindowToListInOrderLocked(win, true);
1933 adjustInputMethodDialogsLocked();
1934 imMayMove = false;
1935 } else {
1936 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001937 if (attrs.type == TYPE_WALLPAPER) {
1938 mLastWallpaperTimeoutTime = 0;
1939 adjustWallpaperWindowsLocked();
1940 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001941 adjustWallpaperWindowsLocked();
1942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 }
Romain Guy06882f82009-06-10 13:36:04 -07001944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07001946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07001948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 if (mInTouchMode) {
1950 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
1951 }
1952 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
1953 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
1954 }
Romain Guy06882f82009-06-10 13:36:04 -07001955
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08001956 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07001958 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
1959 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 imMayMove = false;
1961 }
1962 }
Romain Guy06882f82009-06-10 13:36:04 -07001963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07001965 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 }
Romain Guy06882f82009-06-10 13:36:04 -07001967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 assignLayersLocked();
1969 // Don't do layout here, the window must call
1970 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07001971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 //dump();
1973
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08001974 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07001975 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08001976 }
Jeff Brown349703e2010-06-22 01:27:15 -07001977
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 TAG, "New client " + client.asBinder()
1980 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001981
1982 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
1983 reportNewConfig = true;
1984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 }
1986
1987 // sendNewConfiguration() checks caller permissions so we must call it with
1988 // privilege. updateOrientationFromAppTokens() clears and resets the caller
1989 // identity anyway, so it's safe to just clear & restore around this whole
1990 // block.
1991 final long origId = Binder.clearCallingIdentity();
1992 if (reportNewConfig) {
1993 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001994 }
1995 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07001996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 return res;
1998 }
Romain Guy06882f82009-06-10 13:36:04 -07001999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002000 public void removeWindow(Session session, IWindow client) {
2001 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002002 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 if (win == null) {
2004 return;
2005 }
2006 removeWindowLocked(session, win);
2007 }
2008 }
Romain Guy06882f82009-06-10 13:36:04 -07002009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 public void removeWindowLocked(Session session, WindowState win) {
2011
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 TAG, "Remove " + win + " client="
2014 + Integer.toHexString(System.identityHashCode(
2015 win.mClient.asBinder()))
2016 + ", surface=" + win.mSurface);
2017
2018 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002019
Joe Onorato8a9b2202010-02-26 18:56:32 -08002020 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2022 + " mExiting=" + win.mExiting
2023 + " isAnimating=" + win.isAnimating()
2024 + " app-animation="
2025 + (win.mAppToken != null ? win.mAppToken.animation : null)
2026 + " inPendingTransaction="
2027 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2028 + " mDisplayFrozen=" + mDisplayFrozen);
2029 // Visibility of the removed window. Will be used later to update orientation later on.
2030 boolean wasVisible = false;
2031 // First, see if we need to run an animation. If we do, we have
2032 // to hold off on removing the window until the animation is done.
2033 // If the display is frozen, just remove immediately, since the
2034 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002035 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 // If we are not currently running the exit animation, we
2037 // need to see about starting one.
2038 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002040 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2041 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2042 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2043 }
2044 // Try starting an animation.
2045 if (applyAnimationLocked(win, transit, false)) {
2046 win.mExiting = true;
2047 }
2048 }
2049 if (win.mExiting || win.isAnimating()) {
2050 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002051 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 win.mExiting = true;
2053 win.mRemoveOnExit = true;
2054 mLayoutNeeded = true;
2055 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2056 performLayoutAndPlaceSurfacesLocked();
2057 if (win.mAppToken != null) {
2058 win.mAppToken.updateReportedVisibilityLocked();
2059 }
2060 //dump();
2061 Binder.restoreCallingIdentity(origId);
2062 return;
2063 }
2064 }
2065
2066 removeWindowInnerLocked(session, win);
2067 // Removing a visible window will effect the computed orientation
2068 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002069 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002070 != mForcedAppOrientation
2071 && updateOrientationFromAppTokensLocked()) {
2072 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002073 }
2074 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2075 Binder.restoreCallingIdentity(origId);
2076 }
Romain Guy06882f82009-06-10 13:36:04 -07002077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 private void removeWindowInnerLocked(Session session, WindowState win) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002079 mInputMonitor.windowIsBeingRemovedLw(win);
Romain Guy06882f82009-06-10 13:36:04 -07002080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002081 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 if (mInputMethodTarget == win) {
2084 moveInputMethodWindowsIfNeededLocked(false);
2085 }
Romain Guy06882f82009-06-10 13:36:04 -07002086
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002087 if (false) {
2088 RuntimeException e = new RuntimeException("here");
2089 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002090 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002091 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 mPolicy.removeWindowLw(win);
2094 win.removeLocked();
2095
2096 mWindowMap.remove(win.mClient.asBinder());
2097 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002098 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002099 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100
2101 if (mInputMethodWindow == win) {
2102 mInputMethodWindow = null;
2103 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2104 mInputMethodDialogs.remove(win);
2105 }
Romain Guy06882f82009-06-10 13:36:04 -07002106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 final WindowToken token = win.mToken;
2108 final AppWindowToken atoken = win.mAppToken;
2109 token.windows.remove(win);
2110 if (atoken != null) {
2111 atoken.allAppWindows.remove(win);
2112 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002113 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 TAG, "**** Removing window " + win + ": count="
2115 + token.windows.size());
2116 if (token.windows.size() == 0) {
2117 if (!token.explicit) {
2118 mTokenMap.remove(token.token);
2119 mTokenList.remove(token);
2120 } else if (atoken != null) {
2121 atoken.firstWindowDrawn = false;
2122 }
2123 }
2124
2125 if (atoken != null) {
2126 if (atoken.startingWindow == win) {
2127 atoken.startingWindow = null;
2128 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2129 // If this is the last window and we had requested a starting
2130 // transition window, well there is no point now.
2131 atoken.startingData = null;
2132 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2133 // If this is the last window except for a starting transition
2134 // window, we need to get rid of the starting transition.
2135 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002136 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 + ": no more real windows");
2138 }
2139 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2140 mH.sendMessage(m);
2141 }
2142 }
Romain Guy06882f82009-06-10 13:36:04 -07002143
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002144 if (win.mAttrs.type == TYPE_WALLPAPER) {
2145 mLastWallpaperTimeoutTime = 0;
2146 adjustWallpaperWindowsLocked();
2147 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002148 adjustWallpaperWindowsLocked();
2149 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 if (!mInLayout) {
2152 assignLayersLocked();
2153 mLayoutNeeded = true;
2154 performLayoutAndPlaceSurfacesLocked();
2155 if (win.mAppToken != null) {
2156 win.mAppToken.updateReportedVisibilityLocked();
2157 }
2158 }
2159 }
2160
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002161 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2162 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2163 + ": " + msg + " / " + w.mAttrs.getTitle();
2164 if (where != null) {
2165 Slog.i(TAG, str, where);
2166 } else {
2167 Slog.i(TAG, str);
2168 }
2169 }
2170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2172 long origId = Binder.clearCallingIdentity();
2173 try {
2174 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002175 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002177 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 Surface.openTransaction();
2179 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002180 if (SHOW_TRANSACTIONS) logSurface(w,
2181 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 w.mSurface.setTransparentRegionHint(region);
2183 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002184 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 Surface.closeTransaction();
2186 }
2187 }
2188 }
2189 } finally {
2190 Binder.restoreCallingIdentity(origId);
2191 }
2192 }
2193
2194 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002195 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 Rect visibleInsets) {
2197 long origId = Binder.clearCallingIdentity();
2198 try {
2199 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002200 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 if (w != null) {
2202 w.mGivenInsetsPending = false;
2203 w.mGivenContentInsets.set(contentInsets);
2204 w.mGivenVisibleInsets.set(visibleInsets);
2205 w.mTouchableInsets = touchableInsets;
2206 mLayoutNeeded = true;
2207 performLayoutAndPlaceSurfacesLocked();
2208 }
2209 }
2210 } finally {
2211 Binder.restoreCallingIdentity(origId);
2212 }
2213 }
Romain Guy06882f82009-06-10 13:36:04 -07002214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 public void getWindowDisplayFrame(Session session, IWindow client,
2216 Rect outDisplayFrame) {
2217 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002218 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002219 if (win == null) {
2220 outDisplayFrame.setEmpty();
2221 return;
2222 }
2223 outDisplayFrame.set(win.mDisplayFrame);
2224 }
2225 }
2226
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002227 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2228 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002229 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2230 window.mWallpaperX = x;
2231 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002232 window.mWallpaperXStep = xStep;
2233 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002234 if (updateWallpaperOffsetLocked(window, true)) {
2235 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002236 }
2237 }
2238 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002239
Dianne Hackborn75804932009-10-20 20:15:20 -07002240 void wallpaperCommandComplete(IBinder window, Bundle result) {
2241 synchronized (mWindowMap) {
2242 if (mWaitingOnWallpaper != null &&
2243 mWaitingOnWallpaper.mClient.asBinder() == window) {
2244 mWaitingOnWallpaper = null;
2245 mWindowMap.notifyAll();
2246 }
2247 }
2248 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002249
Dianne Hackborn75804932009-10-20 20:15:20 -07002250 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2251 String action, int x, int y, int z, Bundle extras, boolean sync) {
2252 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2253 || window == mUpperWallpaperTarget) {
2254 boolean doWait = sync;
2255 int curTokenIndex = mWallpaperTokens.size();
2256 while (curTokenIndex > 0) {
2257 curTokenIndex--;
2258 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2259 int curWallpaperIndex = token.windows.size();
2260 while (curWallpaperIndex > 0) {
2261 curWallpaperIndex--;
2262 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2263 try {
2264 wallpaper.mClient.dispatchWallpaperCommand(action,
2265 x, y, z, extras, sync);
2266 // We only want to be synchronous with one wallpaper.
2267 sync = false;
2268 } catch (RemoteException e) {
2269 }
2270 }
2271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002272
Dianne Hackborn75804932009-10-20 20:15:20 -07002273 if (doWait) {
2274 // XXX Need to wait for result.
2275 }
2276 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002277
Dianne Hackborn75804932009-10-20 20:15:20 -07002278 return null;
2279 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 public int relayoutWindow(Session session, IWindow client,
2282 WindowManager.LayoutParams attrs, int requestedWidth,
2283 int requestedHeight, int viewVisibility, boolean insetsPending,
2284 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002285 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 boolean displayed = false;
2287 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002288 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002292 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 if (win == null) {
2294 return 0;
2295 }
2296 win.mRequestedWidth = requestedWidth;
2297 win.mRequestedHeight = requestedHeight;
2298
2299 if (attrs != null) {
2300 mPolicy.adjustWindowParamsLw(attrs);
2301 }
Romain Guy06882f82009-06-10 13:36:04 -07002302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 int attrChanges = 0;
2304 int flagChanges = 0;
2305 if (attrs != null) {
2306 flagChanges = win.mAttrs.flags ^= attrs.flags;
2307 attrChanges = win.mAttrs.copyFrom(attrs);
2308 }
2309
Joe Onorato8a9b2202010-02-26 18:56:32 -08002310 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311
2312 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2313 win.mAlpha = attrs.alpha;
2314 }
2315
2316 final boolean scaledWindow =
2317 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2318
2319 if (scaledWindow) {
2320 // requested{Width|Height} Surface's physical size
2321 // attrs.{width|height} Size on screen
2322 win.mHScale = (attrs.width != requestedWidth) ?
2323 (attrs.width / (float)requestedWidth) : 1.0f;
2324 win.mVScale = (attrs.height != requestedHeight) ?
2325 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002326 } else {
2327 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 }
2329
2330 boolean imMayMove = (flagChanges&(
2331 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2332 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 boolean focusMayChange = win.mViewVisibility != viewVisibility
2335 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2336 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002337
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002338 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2339 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 win.mRelayoutCalled = true;
2342 final int oldVisibility = win.mViewVisibility;
2343 win.mViewVisibility = viewVisibility;
2344 if (viewVisibility == View.VISIBLE &&
2345 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2346 displayed = !win.isVisibleLw();
2347 if (win.mExiting) {
2348 win.mExiting = false;
2349 win.mAnimation = null;
2350 }
2351 if (win.mDestroying) {
2352 win.mDestroying = false;
2353 mDestroySurface.remove(win);
2354 }
2355 if (oldVisibility == View.GONE) {
2356 win.mEnterAnimationPending = true;
2357 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002358 if (displayed) {
2359 if (win.mSurface != null && !win.mDrawPending
2360 && !win.mCommitDrawPending && !mDisplayFrozen
2361 && mPolicy.isScreenOn()) {
2362 applyEnterAnimationLocked(win);
2363 }
2364 if ((win.mAttrs.flags
2365 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2366 if (DEBUG_VISIBILITY) Slog.v(TAG,
2367 "Relayout window turning screen on: " + win);
2368 win.mTurnOnScreen = true;
2369 }
2370 int diff = 0;
2371 if (win.mConfiguration != mCurConfiguration
2372 && (win.mConfiguration == null
2373 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2374 win.mConfiguration = mCurConfiguration;
2375 if (DEBUG_CONFIGURATION) {
2376 Slog.i(TAG, "Window " + win + " visible with new config: "
2377 + win.mConfiguration + " / 0x"
2378 + Integer.toHexString(diff));
2379 }
2380 outConfig.setTo(mCurConfiguration);
2381 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2384 // To change the format, we need to re-build the surface.
2385 win.destroySurfaceLocked();
2386 displayed = true;
2387 }
2388 try {
2389 Surface surface = win.createSurfaceLocked();
2390 if (surface != null) {
2391 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002392 win.mReportDestroySurface = false;
2393 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002394 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002395 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002397 // For some reason there isn't a surface. Clear the
2398 // caller's object so they see the same state.
2399 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 }
2401 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002402 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002403 + client + " (" + win.mAttrs.getTitle() + ")",
2404 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 Binder.restoreCallingIdentity(origId);
2406 return 0;
2407 }
2408 if (displayed) {
2409 focusMayChange = true;
2410 }
2411 if (win.mAttrs.type == TYPE_INPUT_METHOD
2412 && mInputMethodWindow == null) {
2413 mInputMethodWindow = win;
2414 imMayMove = true;
2415 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002416 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2417 && win.mAppToken != null
2418 && win.mAppToken.startingWindow != null) {
2419 // Special handling of starting window over the base
2420 // window of the app: propagate lock screen flags to it,
2421 // to provide the correct semantics while starting.
2422 final int mask =
2423 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002424 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2425 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002426 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2427 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 } else {
2430 win.mEnterAnimationPending = false;
2431 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002432 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002433 + ": mExiting=" + win.mExiting
2434 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 // If we are not currently running the exit animation, we
2436 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002437 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 // Try starting an animation; if there isn't one, we
2439 // can destroy the surface right away.
2440 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2441 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2442 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2443 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002444 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002446 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 win.mExiting = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002448 mInputMonitor.windowIsBecomingInvisibleLw(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 } else if (win.isAnimating()) {
2450 // Currently in a hide animation... turn this into
2451 // an exit.
2452 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002453 } else if (win == mWallpaperTarget) {
2454 // If the wallpaper is currently behind this
2455 // window, we need to change both of them inside
2456 // of a transaction to avoid artifacts.
2457 win.mExiting = true;
2458 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 } else {
2460 if (mInputMethodWindow == win) {
2461 mInputMethodWindow = null;
2462 }
2463 win.destroySurfaceLocked();
2464 }
2465 }
2466 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002467
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002468 if (win.mSurface == null || (win.getAttrs().flags
2469 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2470 || win.mSurfacePendingDestroy) {
2471 // We are being called from a local process, which
2472 // means outSurface holds its current surface. Ensure the
2473 // surface object is cleared, but we don't want it actually
2474 // destroyed at this point.
2475 win.mSurfacePendingDestroy = false;
2476 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002477 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002478 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002479 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002480 "Keeping surface, will report destroy: " + win);
2481 win.mReportDestroySurface = true;
2482 outSurface.copyFrom(win.mSurface);
2483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 }
2485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 if (focusMayChange) {
2487 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2488 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 imMayMove = false;
2490 }
2491 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2492 }
Romain Guy06882f82009-06-10 13:36:04 -07002493
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002494 // updateFocusedWindowLocked() already assigned layers so we only need to
2495 // reassign them at this point if the IM window state gets shuffled
2496 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002499 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2500 // Little hack here -- we -should- be able to rely on the
2501 // function to return true if the IME has moved and needs
2502 // its layer recomputed. However, if the IME was hidden
2503 // and isn't actually moved in the list, its layer may be
2504 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002505 assignLayers = true;
2506 }
2507 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002508 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002509 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002510 assignLayers = true;
2511 }
2512 }
Romain Guy06882f82009-06-10 13:36:04 -07002513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 mLayoutNeeded = true;
2515 win.mGivenInsetsPending = insetsPending;
2516 if (assignLayers) {
2517 assignLayersLocked();
2518 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002519 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002521 if (displayed && win.mIsWallpaper) {
2522 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002523 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525 if (win.mAppToken != null) {
2526 win.mAppToken.updateReportedVisibilityLocked();
2527 }
2528 outFrame.set(win.mFrame);
2529 outContentInsets.set(win.mContentInsets);
2530 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002531 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002532 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002533 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 + ", requestedHeight=" + requestedHeight
2535 + ", viewVisibility=" + viewVisibility
2536 + "\nRelayout returning frame=" + outFrame
2537 + ", surface=" + outSurface);
2538
Joe Onorato8a9b2202010-02-26 18:56:32 -08002539 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002540 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2541
2542 inTouchMode = mInTouchMode;
2543 }
2544
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002545 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 sendNewConfiguration();
2547 }
Romain Guy06882f82009-06-10 13:36:04 -07002548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002551 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2552 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2553 }
2554
2555 public void finishDrawingWindow(Session session, IWindow client) {
2556 final long origId = Binder.clearCallingIdentity();
2557 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002558 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002560 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2561 adjustWallpaperWindowsLocked();
2562 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 mLayoutNeeded = true;
2564 performLayoutAndPlaceSurfacesLocked();
2565 }
2566 }
2567 Binder.restoreCallingIdentity(origId);
2568 }
2569
2570 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002571 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 + (lp != null ? lp.packageName : null)
2573 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2574 if (lp != null && lp.windowAnimations != 0) {
2575 // If this is a system resource, don't try to load it from the
2576 // application resources. It is nice to avoid loading application
2577 // resources if we can.
2578 String packageName = lp.packageName != null ? lp.packageName : "android";
2579 int resId = lp.windowAnimations;
2580 if ((resId&0xFF000000) == 0x01000000) {
2581 packageName = "android";
2582 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002583 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 + packageName);
2585 return AttributeCache.instance().get(packageName, resId,
2586 com.android.internal.R.styleable.WindowAnimation);
2587 }
2588 return null;
2589 }
Romain Guy06882f82009-06-10 13:36:04 -07002590
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002591 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002592 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002593 + packageName + " resId=0x" + Integer.toHexString(resId));
2594 if (packageName != null) {
2595 if ((resId&0xFF000000) == 0x01000000) {
2596 packageName = "android";
2597 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002598 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002599 + packageName);
2600 return AttributeCache.instance().get(packageName, resId,
2601 com.android.internal.R.styleable.WindowAnimation);
2602 }
2603 return null;
2604 }
2605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 private void applyEnterAnimationLocked(WindowState win) {
2607 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2608 if (win.mEnterAnimationPending) {
2609 win.mEnterAnimationPending = false;
2610 transit = WindowManagerPolicy.TRANSIT_ENTER;
2611 }
2612
2613 applyAnimationLocked(win, transit, true);
2614 }
2615
2616 private boolean applyAnimationLocked(WindowState win,
2617 int transit, boolean isEntrance) {
2618 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2619 // If we are trying to apply an animation, but already running
2620 // an animation of the same type, then just leave that one alone.
2621 return true;
2622 }
Romain Guy06882f82009-06-10 13:36:04 -07002623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 // Only apply an animation if the display isn't frozen. If it is
2625 // frozen, there is no reason to animate and it can cause strange
2626 // artifacts when we unfreeze the display if some different animation
2627 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002628 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002629 int anim = mPolicy.selectAnimationLw(win, transit);
2630 int attr = -1;
2631 Animation a = null;
2632 if (anim != 0) {
2633 a = AnimationUtils.loadAnimation(mContext, anim);
2634 } else {
2635 switch (transit) {
2636 case WindowManagerPolicy.TRANSIT_ENTER:
2637 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2638 break;
2639 case WindowManagerPolicy.TRANSIT_EXIT:
2640 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2641 break;
2642 case WindowManagerPolicy.TRANSIT_SHOW:
2643 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2644 break;
2645 case WindowManagerPolicy.TRANSIT_HIDE:
2646 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2647 break;
2648 }
2649 if (attr >= 0) {
2650 a = loadAnimation(win.mAttrs, attr);
2651 }
2652 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002653 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2655 + " mAnimation=" + win.mAnimation
2656 + " isEntrance=" + isEntrance);
2657 if (a != null) {
2658 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002659 RuntimeException e = null;
2660 if (!HIDE_STACK_CRAWLS) {
2661 e = new RuntimeException();
2662 e.fillInStackTrace();
2663 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002664 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 }
2666 win.setAnimation(a);
2667 win.mAnimationIsEntrance = isEntrance;
2668 }
2669 } else {
2670 win.clearAnimation();
2671 }
2672
2673 return win.mAnimation != null;
2674 }
2675
2676 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2677 int anim = 0;
2678 Context context = mContext;
2679 if (animAttr >= 0) {
2680 AttributeCache.Entry ent = getCachedAnimations(lp);
2681 if (ent != null) {
2682 context = ent.context;
2683 anim = ent.array.getResourceId(animAttr, 0);
2684 }
2685 }
2686 if (anim != 0) {
2687 return AnimationUtils.loadAnimation(context, anim);
2688 }
2689 return null;
2690 }
Romain Guy06882f82009-06-10 13:36:04 -07002691
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002692 private Animation loadAnimation(String packageName, int resId) {
2693 int anim = 0;
2694 Context context = mContext;
2695 if (resId >= 0) {
2696 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2697 if (ent != null) {
2698 context = ent.context;
2699 anim = resId;
2700 }
2701 }
2702 if (anim != 0) {
2703 return AnimationUtils.loadAnimation(context, anim);
2704 }
2705 return null;
2706 }
2707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 private boolean applyAnimationLocked(AppWindowToken wtoken,
2709 WindowManager.LayoutParams lp, int transit, boolean enter) {
2710 // Only apply an animation if the display isn't frozen. If it is
2711 // frozen, there is no reason to animate and it can cause strange
2712 // artifacts when we unfreeze the display if some different animation
2713 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002714 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002715 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002716 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002717 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002719 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002720 } else if (mNextAppTransitionPackage != null) {
2721 a = loadAnimation(mNextAppTransitionPackage, enter ?
2722 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002723 } else {
2724 int animAttr = 0;
2725 switch (transit) {
2726 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2727 animAttr = enter
2728 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2729 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2730 break;
2731 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2732 animAttr = enter
2733 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2734 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2735 break;
2736 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2737 animAttr = enter
2738 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2739 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2740 break;
2741 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2742 animAttr = enter
2743 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2744 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2745 break;
2746 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2747 animAttr = enter
2748 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2749 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2750 break;
2751 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2752 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002753 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002754 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2755 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002756 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002757 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002758 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2759 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002760 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002761 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002762 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002763 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2764 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2765 break;
2766 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2767 animAttr = enter
2768 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2769 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2770 break;
2771 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2772 animAttr = enter
2773 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2774 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002775 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002776 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002777 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002778 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002779 + " anim=" + a
2780 + " animAttr=0x" + Integer.toHexString(animAttr)
2781 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 if (a != null) {
2784 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002785 RuntimeException e = null;
2786 if (!HIDE_STACK_CRAWLS) {
2787 e = new RuntimeException();
2788 e.fillInStackTrace();
2789 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002790 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 }
2792 wtoken.setAnimation(a);
2793 }
2794 } else {
2795 wtoken.clearAnimation();
2796 }
2797
2798 return wtoken.animation != null;
2799 }
2800
2801 // -------------------------------------------------------------
2802 // Application Window Tokens
2803 // -------------------------------------------------------------
2804
2805 public void validateAppTokens(List tokens) {
2806 int v = tokens.size()-1;
2807 int m = mAppTokens.size()-1;
2808 while (v >= 0 && m >= 0) {
2809 AppWindowToken wtoken = mAppTokens.get(m);
2810 if (wtoken.removed) {
2811 m--;
2812 continue;
2813 }
2814 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002815 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2817 }
2818 v--;
2819 m--;
2820 }
2821 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002822 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 v--;
2824 }
2825 while (m >= 0) {
2826 AppWindowToken wtoken = mAppTokens.get(m);
2827 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002828 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829 }
2830 m--;
2831 }
2832 }
2833
2834 boolean checkCallingPermission(String permission, String func) {
2835 // Quick check: if the calling permission is me, it's all okay.
2836 if (Binder.getCallingPid() == Process.myPid()) {
2837 return true;
2838 }
Romain Guy06882f82009-06-10 13:36:04 -07002839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 if (mContext.checkCallingPermission(permission)
2841 == PackageManager.PERMISSION_GRANTED) {
2842 return true;
2843 }
2844 String msg = "Permission Denial: " + func + " from pid="
2845 + Binder.getCallingPid()
2846 + ", uid=" + Binder.getCallingUid()
2847 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002848 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002849 return false;
2850 }
Romain Guy06882f82009-06-10 13:36:04 -07002851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002852 AppWindowToken findAppWindowToken(IBinder token) {
2853 WindowToken wtoken = mTokenMap.get(token);
2854 if (wtoken == null) {
2855 return null;
2856 }
2857 return wtoken.appWindowToken;
2858 }
Romain Guy06882f82009-06-10 13:36:04 -07002859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 public void addWindowToken(IBinder token, int type) {
2861 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2862 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002863 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 }
Romain Guy06882f82009-06-10 13:36:04 -07002865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 synchronized(mWindowMap) {
2867 WindowToken wtoken = mTokenMap.get(token);
2868 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002869 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 return;
2871 }
2872 wtoken = new WindowToken(token, type, true);
2873 mTokenMap.put(token, wtoken);
2874 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002875 if (type == TYPE_WALLPAPER) {
2876 mWallpaperTokens.add(wtoken);
2877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 }
2879 }
Romain Guy06882f82009-06-10 13:36:04 -07002880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 public void removeWindowToken(IBinder token) {
2882 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2883 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002884 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002885 }
2886
2887 final long origId = Binder.clearCallingIdentity();
2888 synchronized(mWindowMap) {
2889 WindowToken wtoken = mTokenMap.remove(token);
2890 mTokenList.remove(wtoken);
2891 if (wtoken != null) {
2892 boolean delayed = false;
2893 if (!wtoken.hidden) {
2894 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07002895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 final int N = wtoken.windows.size();
2897 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07002898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 for (int i=0; i<N; i++) {
2900 WindowState win = wtoken.windows.get(i);
2901
2902 if (win.isAnimating()) {
2903 delayed = true;
2904 }
Romain Guy06882f82009-06-10 13:36:04 -07002905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 if (win.isVisibleNow()) {
2907 applyAnimationLocked(win,
2908 WindowManagerPolicy.TRANSIT_EXIT, false);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002909 mInputMonitor.windowIsBeingRemovedLw(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 changed = true;
2911 }
2912 }
2913
2914 if (changed) {
2915 mLayoutNeeded = true;
2916 performLayoutAndPlaceSurfacesLocked();
2917 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2918 }
Romain Guy06882f82009-06-10 13:36:04 -07002919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002920 if (delayed) {
2921 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002922 } else if (wtoken.windowType == TYPE_WALLPAPER) {
2923 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
2925 }
Romain Guy06882f82009-06-10 13:36:04 -07002926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002928 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 }
2930 }
2931 Binder.restoreCallingIdentity(origId);
2932 }
2933
2934 public void addAppToken(int addPos, IApplicationToken token,
2935 int groupId, int requestedOrientation, boolean fullscreen) {
2936 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2937 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002938 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939 }
Jeff Brown349703e2010-06-22 01:27:15 -07002940
2941 // Get the dispatching timeout here while we are not holding any locks so that it
2942 // can be cached by the AppWindowToken. The timeout value is used later by the
2943 // input dispatcher in code that does hold locks. If we did not cache the value
2944 // here we would run the chance of introducing a deadlock between the window manager
2945 // (which holds locks while updating the input dispatcher state) and the activity manager
2946 // (which holds locks while querying the application token).
2947 long inputDispatchingTimeoutNanos;
2948 try {
2949 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
2950 } catch (RemoteException ex) {
2951 Slog.w(TAG, "Could not get dispatching timeout.", ex);
2952 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
2953 }
Romain Guy06882f82009-06-10 13:36:04 -07002954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 synchronized(mWindowMap) {
2956 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
2957 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002958 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 return;
2960 }
2961 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07002962 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002963 wtoken.groupId = groupId;
2964 wtoken.appFullscreen = fullscreen;
2965 wtoken.requestedOrientation = requestedOrientation;
2966 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002967 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002968 mTokenMap.put(token.asBinder(), wtoken);
2969 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07002970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 // Application tokens start out hidden.
2972 wtoken.hidden = true;
2973 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07002974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 //dump();
2976 }
2977 }
Romain Guy06882f82009-06-10 13:36:04 -07002978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 public void setAppGroupId(IBinder token, int groupId) {
2980 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2981 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002982 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 }
2984
2985 synchronized(mWindowMap) {
2986 AppWindowToken wtoken = findAppWindowToken(token);
2987 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002988 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 return;
2990 }
2991 wtoken.groupId = groupId;
2992 }
2993 }
Romain Guy06882f82009-06-10 13:36:04 -07002994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 public int getOrientationFromWindowsLocked() {
2996 int pos = mWindows.size() - 1;
2997 while (pos >= 0) {
2998 WindowState wtoken = (WindowState) mWindows.get(pos);
2999 pos--;
3000 if (wtoken.mAppToken != null) {
3001 // We hit an application window. so the orientation will be determined by the
3002 // app window. No point in continuing further.
3003 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3004 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003005 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 continue;
3007 }
3008 int req = wtoken.mAttrs.screenOrientation;
3009 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3010 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3011 continue;
3012 } else {
3013 return req;
3014 }
3015 }
3016 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3017 }
Romain Guy06882f82009-06-10 13:36:04 -07003018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003020 int pos = mAppTokens.size() - 1;
3021 int curGroup = 0;
3022 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3023 boolean findingBehind = false;
3024 boolean haveGroup = false;
3025 boolean lastFullscreen = false;
3026 while (pos >= 0) {
3027 AppWindowToken wtoken = mAppTokens.get(pos);
3028 pos--;
3029 // if we're about to tear down this window and not seek for
3030 // the behind activity, don't use it for orientation
3031 if (!findingBehind
3032 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3033 continue;
3034 }
3035
3036 if (!haveGroup) {
3037 // We ignore any hidden applications on the top.
3038 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003039 continue;
3040 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003041 haveGroup = true;
3042 curGroup = wtoken.groupId;
3043 lastOrientation = wtoken.requestedOrientation;
3044 } else if (curGroup != wtoken.groupId) {
3045 // If we have hit a new application group, and the bottom
3046 // of the previous group didn't explicitly say to use
3047 // the orientation behind it, and the last app was
3048 // full screen, then we'll stick with the
3049 // user's orientation.
3050 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3051 && lastFullscreen) {
3052 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003055 int or = wtoken.requestedOrientation;
3056 // If this application is fullscreen, and didn't explicitly say
3057 // to use the orientation behind it, then just take whatever
3058 // orientation it has and ignores whatever is under it.
3059 lastFullscreen = wtoken.appFullscreen;
3060 if (lastFullscreen
3061 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3062 return or;
3063 }
3064 // If this application has requested an explicit orientation,
3065 // then use it.
3066 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3067 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3068 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3069 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3070 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3071 return or;
3072 }
3073 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3074 }
3075 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 }
Romain Guy06882f82009-06-10 13:36:04 -07003077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003079 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003080 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3081 "updateOrientationFromAppTokens()")) {
3082 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3083 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003084
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003085 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003087
3088 synchronized(mWindowMap) {
3089 if (updateOrientationFromAppTokensLocked()) {
3090 if (freezeThisOneIfNeeded != null) {
3091 AppWindowToken wtoken = findAppWindowToken(
3092 freezeThisOneIfNeeded);
3093 if (wtoken != null) {
3094 startAppFreezingScreenLocked(wtoken,
3095 ActivityInfo.CONFIG_ORIENTATION);
3096 }
3097 }
3098 config = computeNewConfigurationLocked();
3099
3100 } else if (currentConfig != null) {
3101 // No obvious action we need to take, but if our current
3102 // state mismatches the activity maanager's, update it
3103 mTempConfiguration.setToDefaults();
3104 if (computeNewConfigurationLocked(mTempConfiguration)) {
3105 if (currentConfig.diff(mTempConfiguration) != 0) {
3106 mWaitingForConfig = true;
3107 mLayoutNeeded = true;
3108 startFreezingDisplayLocked();
3109 config = new Configuration(mTempConfiguration);
3110 }
3111 }
3112 }
3113 }
3114
Dianne Hackborncfaef692009-06-15 14:24:44 -07003115 Binder.restoreCallingIdentity(ident);
3116 return config;
3117 }
3118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003120 * Determine the new desired orientation of the display, returning
3121 * a non-null new Configuration if it has changed from the current
3122 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3123 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3124 * SCREEN. This will typically be done for you if you call
3125 * sendNewConfiguration().
3126 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 * The orientation is computed from non-application windows first. If none of
3128 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003129 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003130 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3131 * android.os.IBinder)
3132 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003133 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003134 if (mDisplayFrozen) {
3135 // If the display is frozen, some activities may be in the middle
3136 // of restarting, and thus have removed their old window. If the
3137 // window has the flag to hide the lock screen, then the lock screen
3138 // can re-appear and inflict its own orientation on us. Keep the
3139 // orientation stable until this all settles down.
3140 return false;
3141 }
3142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144 long ident = Binder.clearCallingIdentity();
3145 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003146 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 mForcedAppOrientation = req;
3150 //send a message to Policy indicating orientation change to take
3151 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003152 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003153 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3154 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3155 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 }
3157 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003158
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003159 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 } finally {
3161 Binder.restoreCallingIdentity(ident);
3162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 }
Romain Guy06882f82009-06-10 13:36:04 -07003164
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003165 int computeForcedAppOrientationLocked() {
3166 int req = getOrientationFromWindowsLocked();
3167 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3168 req = getOrientationFromAppTokensLocked();
3169 }
3170 return req;
3171 }
Romain Guy06882f82009-06-10 13:36:04 -07003172
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003173 public void setNewConfiguration(Configuration config) {
3174 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3175 "setNewConfiguration()")) {
3176 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3177 }
3178
3179 synchronized(mWindowMap) {
3180 mCurConfiguration = new Configuration(config);
3181 mWaitingForConfig = false;
3182 performLayoutAndPlaceSurfacesLocked();
3183 }
3184 }
3185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3187 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3188 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003189 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 }
Romain Guy06882f82009-06-10 13:36:04 -07003191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003192 synchronized(mWindowMap) {
3193 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3194 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003195 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 return;
3197 }
Romain Guy06882f82009-06-10 13:36:04 -07003198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003199 wtoken.requestedOrientation = requestedOrientation;
3200 }
3201 }
Romain Guy06882f82009-06-10 13:36:04 -07003202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003203 public int getAppOrientation(IApplicationToken token) {
3204 synchronized(mWindowMap) {
3205 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3206 if (wtoken == null) {
3207 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3208 }
Romain Guy06882f82009-06-10 13:36:04 -07003209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003210 return wtoken.requestedOrientation;
3211 }
3212 }
Romain Guy06882f82009-06-10 13:36:04 -07003213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3215 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3216 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003217 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 }
3219
3220 synchronized(mWindowMap) {
3221 boolean changed = false;
3222 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003223 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 changed = mFocusedApp != null;
3225 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003226 if (changed) {
3227 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 } else {
3230 AppWindowToken newFocus = findAppWindowToken(token);
3231 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003232 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 return;
3234 }
3235 changed = mFocusedApp != newFocus;
3236 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003238 if (changed) {
3239 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 }
3242
3243 if (moveFocusNow && changed) {
3244 final long origId = Binder.clearCallingIdentity();
3245 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3246 Binder.restoreCallingIdentity(origId);
3247 }
3248 }
3249 }
3250
3251 public void prepareAppTransition(int transit) {
3252 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3253 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003254 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 }
Romain Guy06882f82009-06-10 13:36:04 -07003256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003257 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003258 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003259 TAG, "Prepare app transition: transit=" + transit
3260 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003261 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003262 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3263 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003265 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3266 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3267 // Opening a new task always supersedes a close for the anim.
3268 mNextAppTransition = transit;
3269 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3270 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3271 // Opening a new activity always supersedes a close for the anim.
3272 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 }
3274 mAppTransitionReady = false;
3275 mAppTransitionTimeout = false;
3276 mStartingIconInTransition = false;
3277 mSkipAppTransitionAnimation = false;
3278 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3279 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3280 5000);
3281 }
3282 }
3283 }
3284
3285 public int getPendingAppTransition() {
3286 return mNextAppTransition;
3287 }
Romain Guy06882f82009-06-10 13:36:04 -07003288
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003289 public void overridePendingAppTransition(String packageName,
3290 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003291 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003292 mNextAppTransitionPackage = packageName;
3293 mNextAppTransitionEnter = enterAnim;
3294 mNextAppTransitionExit = exitAnim;
3295 }
3296 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 public void executeAppTransition() {
3299 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3300 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003301 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 }
Romain Guy06882f82009-06-10 13:36:04 -07003303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003305 if (DEBUG_APP_TRANSITIONS) {
3306 RuntimeException e = new RuntimeException("here");
3307 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003308 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003309 + mNextAppTransition, e);
3310 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003311 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 mAppTransitionReady = true;
3313 final long origId = Binder.clearCallingIdentity();
3314 performLayoutAndPlaceSurfacesLocked();
3315 Binder.restoreCallingIdentity(origId);
3316 }
3317 }
3318 }
3319
3320 public void setAppStartingWindow(IBinder token, String pkg,
3321 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3322 IBinder transferFrom, boolean createIfNeeded) {
3323 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3324 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003325 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 }
3327
3328 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003329 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3331 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003333 AppWindowToken wtoken = findAppWindowToken(token);
3334 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003335 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 return;
3337 }
3338
3339 // If the display is frozen, we won't do anything until the
3340 // actual window is displayed so there is no reason to put in
3341 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003342 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 return;
3344 }
Romain Guy06882f82009-06-10 13:36:04 -07003345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 if (wtoken.startingData != null) {
3347 return;
3348 }
Romain Guy06882f82009-06-10 13:36:04 -07003349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350 if (transferFrom != null) {
3351 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3352 if (ttoken != null) {
3353 WindowState startingWindow = ttoken.startingWindow;
3354 if (startingWindow != null) {
3355 if (mStartingIconInTransition) {
3356 // In this case, the starting icon has already
3357 // been displayed, so start letting windows get
3358 // shown immediately without any more transitions.
3359 mSkipAppTransitionAnimation = true;
3360 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003361 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 "Moving existing starting from " + ttoken
3363 + " to " + wtoken);
3364 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 // Transfer the starting window over to the new
3367 // token.
3368 wtoken.startingData = ttoken.startingData;
3369 wtoken.startingView = ttoken.startingView;
3370 wtoken.startingWindow = startingWindow;
3371 ttoken.startingData = null;
3372 ttoken.startingView = null;
3373 ttoken.startingWindow = null;
3374 ttoken.startingMoved = true;
3375 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003376 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003378 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003379 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003381 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 ttoken.windows.remove(startingWindow);
3383 ttoken.allAppWindows.remove(startingWindow);
3384 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 // Propagate other interesting state between the
3387 // tokens. If the old token is displayed, we should
3388 // immediately force the new one to be displayed. If
3389 // it is animating, we need to move that animation to
3390 // the new one.
3391 if (ttoken.allDrawn) {
3392 wtoken.allDrawn = true;
3393 }
3394 if (ttoken.firstWindowDrawn) {
3395 wtoken.firstWindowDrawn = true;
3396 }
3397 if (!ttoken.hidden) {
3398 wtoken.hidden = false;
3399 wtoken.hiddenRequested = false;
3400 wtoken.willBeHidden = false;
3401 }
3402 if (wtoken.clientHidden != ttoken.clientHidden) {
3403 wtoken.clientHidden = ttoken.clientHidden;
3404 wtoken.sendAppVisibilityToClients();
3405 }
3406 if (ttoken.animation != null) {
3407 wtoken.animation = ttoken.animation;
3408 wtoken.animating = ttoken.animating;
3409 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3410 ttoken.animation = null;
3411 ttoken.animLayerAdjustment = 0;
3412 wtoken.updateLayers();
3413 ttoken.updateLayers();
3414 }
Romain Guy06882f82009-06-10 13:36:04 -07003415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 mLayoutNeeded = true;
3418 performLayoutAndPlaceSurfacesLocked();
3419 Binder.restoreCallingIdentity(origId);
3420 return;
3421 } else if (ttoken.startingData != null) {
3422 // The previous app was getting ready to show a
3423 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003424 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425 "Moving pending starting from " + ttoken
3426 + " to " + wtoken);
3427 wtoken.startingData = ttoken.startingData;
3428 ttoken.startingData = null;
3429 ttoken.startingMoved = true;
3430 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3431 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3432 // want to process the message ASAP, before any other queued
3433 // messages.
3434 mH.sendMessageAtFrontOfQueue(m);
3435 return;
3436 }
3437 }
3438 }
3439
3440 // There is no existing starting window, and the caller doesn't
3441 // want us to create one, so that's it!
3442 if (!createIfNeeded) {
3443 return;
3444 }
Romain Guy06882f82009-06-10 13:36:04 -07003445
Dianne Hackborn284ac932009-08-28 10:34:25 -07003446 // If this is a translucent or wallpaper window, then don't
3447 // show a starting window -- the current effect (a full-screen
3448 // opaque starting window that fades away to the real contents
3449 // when it is ready) does not work for this.
3450 if (theme != 0) {
3451 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3452 com.android.internal.R.styleable.Window);
3453 if (ent.array.getBoolean(
3454 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3455 return;
3456 }
3457 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003458 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3459 return;
3460 }
3461 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003462 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3463 return;
3464 }
3465 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003467 mStartingIconInTransition = true;
3468 wtoken.startingData = new StartingData(
3469 pkg, theme, nonLocalizedLabel,
3470 labelRes, icon);
3471 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3472 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3473 // want to process the message ASAP, before any other queued
3474 // messages.
3475 mH.sendMessageAtFrontOfQueue(m);
3476 }
3477 }
3478
3479 public void setAppWillBeHidden(IBinder token) {
3480 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3481 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003482 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 }
3484
3485 AppWindowToken wtoken;
3486
3487 synchronized(mWindowMap) {
3488 wtoken = findAppWindowToken(token);
3489 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003490 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 -08003491 return;
3492 }
3493 wtoken.willBeHidden = true;
3494 }
3495 }
Romain Guy06882f82009-06-10 13:36:04 -07003496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3498 boolean visible, int transit, boolean performLayout) {
3499 boolean delayed = false;
3500
3501 if (wtoken.clientHidden == visible) {
3502 wtoken.clientHidden = !visible;
3503 wtoken.sendAppVisibilityToClients();
3504 }
Romain Guy06882f82009-06-10 13:36:04 -07003505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 wtoken.willBeHidden = false;
3507 if (wtoken.hidden == visible) {
3508 final int N = wtoken.allAppWindows.size();
3509 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003510 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3512 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003515
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003516 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 if (wtoken.animation == sDummyAnimation) {
3518 wtoken.animation = null;
3519 }
3520 applyAnimationLocked(wtoken, lp, transit, visible);
3521 changed = true;
3522 if (wtoken.animation != null) {
3523 delayed = runningAppAnimation = true;
3524 }
3525 }
Romain Guy06882f82009-06-10 13:36:04 -07003526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003527 for (int i=0; i<N; i++) {
3528 WindowState win = wtoken.allAppWindows.get(i);
3529 if (win == wtoken.startingWindow) {
3530 continue;
3531 }
3532
3533 if (win.isAnimating()) {
3534 delayed = true;
3535 }
Romain Guy06882f82009-06-10 13:36:04 -07003536
Joe Onorato8a9b2202010-02-26 18:56:32 -08003537 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 //win.dump(" ");
3539 if (visible) {
3540 if (!win.isVisibleNow()) {
3541 if (!runningAppAnimation) {
3542 applyAnimationLocked(win,
3543 WindowManagerPolicy.TRANSIT_ENTER, true);
3544 }
3545 changed = true;
3546 }
3547 } else if (win.isVisibleNow()) {
3548 if (!runningAppAnimation) {
3549 applyAnimationLocked(win,
3550 WindowManagerPolicy.TRANSIT_EXIT, false);
3551 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003552 mInputMonitor.windowIsBecomingInvisibleLw(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 changed = true;
3554 }
3555 }
3556
3557 wtoken.hidden = wtoken.hiddenRequested = !visible;
3558 if (!visible) {
3559 unsetAppFreezingScreenLocked(wtoken, true, true);
3560 } else {
3561 // If we are being set visible, and the starting window is
3562 // not yet displayed, then make sure it doesn't get displayed.
3563 WindowState swin = wtoken.startingWindow;
3564 if (swin != null && (swin.mDrawPending
3565 || swin.mCommitDrawPending)) {
3566 swin.mPolicyVisibility = false;
3567 swin.mPolicyVisibilityAfterAnim = false;
3568 }
3569 }
Romain Guy06882f82009-06-10 13:36:04 -07003570
Joe Onorato8a9b2202010-02-26 18:56:32 -08003571 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3573 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003574
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003575 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003576 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003577 if (performLayout) {
3578 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3579 performLayoutAndPlaceSurfacesLocked();
3580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 }
3582 }
3583
3584 if (wtoken.animation != null) {
3585 delayed = true;
3586 }
Romain Guy06882f82009-06-10 13:36:04 -07003587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 return delayed;
3589 }
3590
3591 public void setAppVisibility(IBinder token, boolean visible) {
3592 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3593 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003594 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 }
3596
3597 AppWindowToken wtoken;
3598
3599 synchronized(mWindowMap) {
3600 wtoken = findAppWindowToken(token);
3601 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003602 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 return;
3604 }
3605
3606 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003607 RuntimeException e = null;
3608 if (!HIDE_STACK_CRAWLS) {
3609 e = new RuntimeException();
3610 e.fillInStackTrace();
3611 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003612 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 + "): mNextAppTransition=" + mNextAppTransition
3614 + " hidden=" + wtoken.hidden
3615 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3616 }
Romain Guy06882f82009-06-10 13:36:04 -07003617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 // If we are preparing an app transition, then delay changing
3619 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003620 if (!mDisplayFrozen && mPolicy.isScreenOn()
3621 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 // Already in requested state, don't do anything more.
3623 if (wtoken.hiddenRequested != visible) {
3624 return;
3625 }
3626 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003627
Joe Onorato8a9b2202010-02-26 18:56:32 -08003628 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 TAG, "Setting dummy animation on: " + wtoken);
3630 wtoken.setDummyAnimation();
3631 mOpeningApps.remove(wtoken);
3632 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003633 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 wtoken.inPendingTransaction = true;
3635 if (visible) {
3636 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637 wtoken.startingDisplayed = false;
3638 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003639
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003640 // If the token is currently hidden (should be the
3641 // common case), then we need to set up to wait for
3642 // its windows to be ready.
3643 if (wtoken.hidden) {
3644 wtoken.allDrawn = false;
3645 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003646
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003647 if (wtoken.clientHidden) {
3648 // In the case where we are making an app visible
3649 // but holding off for a transition, we still need
3650 // to tell the client to make its windows visible so
3651 // they get drawn. Otherwise, we will wait on
3652 // performing the transition until all windows have
3653 // been drawn, they never will be, and we are sad.
3654 wtoken.clientHidden = false;
3655 wtoken.sendAppVisibilityToClients();
3656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 }
3658 } else {
3659 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003660
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003661 // If the token is currently visible (should be the
3662 // common case), then set up to wait for it to be hidden.
3663 if (!wtoken.hidden) {
3664 wtoken.waitingToHide = true;
3665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 }
3667 return;
3668 }
Romain Guy06882f82009-06-10 13:36:04 -07003669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003671 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 wtoken.updateReportedVisibilityLocked();
3673 Binder.restoreCallingIdentity(origId);
3674 }
3675 }
3676
3677 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3678 boolean unfreezeSurfaceNow, boolean force) {
3679 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003680 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 + " force=" + force);
3682 final int N = wtoken.allAppWindows.size();
3683 boolean unfrozeWindows = false;
3684 for (int i=0; i<N; i++) {
3685 WindowState w = wtoken.allAppWindows.get(i);
3686 if (w.mAppFreezing) {
3687 w.mAppFreezing = false;
3688 if (w.mSurface != null && !w.mOrientationChanging) {
3689 w.mOrientationChanging = true;
3690 }
3691 unfrozeWindows = true;
3692 }
3693 }
3694 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003695 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 wtoken.freezingScreen = false;
3697 mAppsFreezingScreen--;
3698 }
3699 if (unfreezeSurfaceNow) {
3700 if (unfrozeWindows) {
3701 mLayoutNeeded = true;
3702 performLayoutAndPlaceSurfacesLocked();
3703 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003704 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 }
3706 }
3707 }
Romain Guy06882f82009-06-10 13:36:04 -07003708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3710 int configChanges) {
3711 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003712 RuntimeException e = null;
3713 if (!HIDE_STACK_CRAWLS) {
3714 e = new RuntimeException();
3715 e.fillInStackTrace();
3716 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003717 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 + ": hidden=" + wtoken.hidden + " freezing="
3719 + wtoken.freezingScreen, e);
3720 }
3721 if (!wtoken.hiddenRequested) {
3722 if (!wtoken.freezingScreen) {
3723 wtoken.freezingScreen = true;
3724 mAppsFreezingScreen++;
3725 if (mAppsFreezingScreen == 1) {
3726 startFreezingDisplayLocked();
3727 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3728 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3729 5000);
3730 }
3731 }
3732 final int N = wtoken.allAppWindows.size();
3733 for (int i=0; i<N; i++) {
3734 WindowState w = wtoken.allAppWindows.get(i);
3735 w.mAppFreezing = true;
3736 }
3737 }
3738 }
Romain Guy06882f82009-06-10 13:36:04 -07003739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740 public void startAppFreezingScreen(IBinder token, int configChanges) {
3741 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3742 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003743 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 }
3745
3746 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003747 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003748 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 return;
3750 }
Romain Guy06882f82009-06-10 13:36:04 -07003751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 AppWindowToken wtoken = findAppWindowToken(token);
3753 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003754 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 return;
3756 }
3757 final long origId = Binder.clearCallingIdentity();
3758 startAppFreezingScreenLocked(wtoken, configChanges);
3759 Binder.restoreCallingIdentity(origId);
3760 }
3761 }
Romain Guy06882f82009-06-10 13:36:04 -07003762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 public void stopAppFreezingScreen(IBinder token, boolean force) {
3764 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3765 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003766 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 }
3768
3769 synchronized(mWindowMap) {
3770 AppWindowToken wtoken = findAppWindowToken(token);
3771 if (wtoken == null || wtoken.appToken == null) {
3772 return;
3773 }
3774 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003775 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3777 unsetAppFreezingScreenLocked(wtoken, true, force);
3778 Binder.restoreCallingIdentity(origId);
3779 }
3780 }
Romain Guy06882f82009-06-10 13:36:04 -07003781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 public void removeAppToken(IBinder token) {
3783 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3784 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003785 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 }
3787
3788 AppWindowToken wtoken = null;
3789 AppWindowToken startingToken = null;
3790 boolean delayed = false;
3791
3792 final long origId = Binder.clearCallingIdentity();
3793 synchronized(mWindowMap) {
3794 WindowToken basewtoken = mTokenMap.remove(token);
3795 mTokenList.remove(basewtoken);
3796 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003797 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003798 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 wtoken.inPendingTransaction = false;
3800 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003801 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 if (mClosingApps.contains(wtoken)) {
3803 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003804 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003806 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 delayed = true;
3808 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003809 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 TAG, "Removing app " + wtoken + " delayed=" + delayed
3811 + " animation=" + wtoken.animation
3812 + " animating=" + wtoken.animating);
3813 if (delayed) {
3814 // set the token aside because it has an active animation to be finished
3815 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003816 } else {
3817 // Make sure there is no animation running on this token,
3818 // so any windows associated with it will be removed as
3819 // soon as their animations are complete
3820 wtoken.animation = null;
3821 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 }
3823 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003824 if (mLastEnterAnimToken == wtoken) {
3825 mLastEnterAnimToken = null;
3826 mLastEnterAnimParams = null;
3827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 wtoken.removed = true;
3829 if (wtoken.startingData != null) {
3830 startingToken = wtoken;
3831 }
3832 unsetAppFreezingScreenLocked(wtoken, true, true);
3833 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003834 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 mFocusedApp = null;
3836 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003837 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 }
3839 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003840 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 }
Romain Guy06882f82009-06-10 13:36:04 -07003842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 if (!delayed && wtoken != null) {
3844 wtoken.updateReportedVisibilityLocked();
3845 }
3846 }
3847 Binder.restoreCallingIdentity(origId);
3848
3849 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003850 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 + startingToken + ": app token removed");
3852 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3853 mH.sendMessage(m);
3854 }
3855 }
3856
3857 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3858 final int NW = token.windows.size();
3859 for (int i=0; i<NW; i++) {
3860 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003861 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003863 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 int j = win.mChildWindows.size();
3865 while (j > 0) {
3866 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003867 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003868 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003869 "Tmp removing child window " + cwin);
3870 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003871 }
3872 }
3873 return NW > 0;
3874 }
3875
3876 void dumpAppTokensLocked() {
3877 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003878 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 }
3880 }
Romain Guy06882f82009-06-10 13:36:04 -07003881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 void dumpWindowsLocked() {
3883 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003884 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 }
3886 }
Romain Guy06882f82009-06-10 13:36:04 -07003887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 private int findWindowOffsetLocked(int tokenPos) {
3889 final int NW = mWindows.size();
3890
3891 if (tokenPos >= mAppTokens.size()) {
3892 int i = NW;
3893 while (i > 0) {
3894 i--;
3895 WindowState win = (WindowState)mWindows.get(i);
3896 if (win.getAppToken() != null) {
3897 return i+1;
3898 }
3899 }
3900 }
3901
3902 while (tokenPos > 0) {
3903 // Find the first app token below the new position that has
3904 // a window displayed.
3905 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003906 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003908 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003909 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07003910 "Skipping token -- currently sending to bottom");
3911 tokenPos--;
3912 continue;
3913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003914 int i = wtoken.windows.size();
3915 while (i > 0) {
3916 i--;
3917 WindowState win = wtoken.windows.get(i);
3918 int j = win.mChildWindows.size();
3919 while (j > 0) {
3920 j--;
3921 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003922 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 for (int pos=NW-1; pos>=0; pos--) {
3924 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003925 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003926 "Found child win @" + (pos+1));
3927 return pos+1;
3928 }
3929 }
3930 }
3931 }
3932 for (int pos=NW-1; pos>=0; pos--) {
3933 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 return pos+1;
3936 }
3937 }
3938 }
3939 tokenPos--;
3940 }
3941
3942 return 0;
3943 }
3944
3945 private final int reAddWindowLocked(int index, WindowState win) {
3946 final int NCW = win.mChildWindows.size();
3947 boolean added = false;
3948 for (int j=0; j<NCW; j++) {
3949 WindowState cwin = (WindowState)win.mChildWindows.get(j);
3950 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003951 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003952 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 mWindows.add(index, win);
3954 index++;
3955 added = true;
3956 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003957 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003958 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 mWindows.add(index, cwin);
3960 index++;
3961 }
3962 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003963 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003964 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 mWindows.add(index, win);
3966 index++;
3967 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003968 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 return index;
3970 }
Romain Guy06882f82009-06-10 13:36:04 -07003971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 private final int reAddAppWindowsLocked(int index, WindowToken token) {
3973 final int NW = token.windows.size();
3974 for (int i=0; i<NW; i++) {
3975 index = reAddWindowLocked(index, token.windows.get(i));
3976 }
3977 return index;
3978 }
3979
3980 public void moveAppToken(int index, IBinder token) {
3981 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3982 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003983 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 }
3985
3986 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003987 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 if (DEBUG_REORDER) dumpAppTokensLocked();
3989 final AppWindowToken wtoken = findAppWindowToken(token);
3990 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003991 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 + token + " (" + wtoken + ")");
3993 return;
3994 }
3995 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003996 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003999 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004000 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004001 if (DEBUG_REORDER) dumpWindowsLocked();
4002 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004003 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 if (DEBUG_REORDER) dumpWindowsLocked();
4005 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004006 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007 if (DEBUG_REORDER) dumpWindowsLocked();
4008 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 mLayoutNeeded = true;
4010 performLayoutAndPlaceSurfacesLocked();
4011 }
4012 Binder.restoreCallingIdentity(origId);
4013 }
4014 }
4015
4016 private void removeAppTokensLocked(List<IBinder> tokens) {
4017 // XXX This should be done more efficiently!
4018 // (take advantage of the fact that both lists should be
4019 // ordered in the same way.)
4020 int N = tokens.size();
4021 for (int i=0; i<N; i++) {
4022 IBinder token = tokens.get(i);
4023 final AppWindowToken wtoken = findAppWindowToken(token);
4024 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004025 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 + token + " (" + wtoken + ")");
4027 i--;
4028 N--;
4029 }
4030 }
4031 }
4032
Dianne Hackborna8f60182009-09-01 19:01:50 -07004033 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4034 boolean updateFocusAndLayout) {
4035 // First remove all of the windows from the list.
4036 tmpRemoveAppWindowsLocked(wtoken);
4037
4038 // Where to start adding?
4039 int pos = findWindowOffsetLocked(tokenPos);
4040
4041 // And now add them back at the correct place.
4042 pos = reAddAppWindowsLocked(pos, wtoken);
4043
4044 if (updateFocusAndLayout) {
4045 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4046 assignLayersLocked();
4047 }
4048 mLayoutNeeded = true;
4049 performLayoutAndPlaceSurfacesLocked();
4050 }
4051 }
4052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4054 // First remove all of the windows from the list.
4055 final int N = tokens.size();
4056 int i;
4057 for (i=0; i<N; i++) {
4058 WindowToken token = mTokenMap.get(tokens.get(i));
4059 if (token != null) {
4060 tmpRemoveAppWindowsLocked(token);
4061 }
4062 }
4063
4064 // Where to start adding?
4065 int pos = findWindowOffsetLocked(tokenPos);
4066
4067 // And now add them back at the correct place.
4068 for (i=0; i<N; i++) {
4069 WindowToken token = mTokenMap.get(tokens.get(i));
4070 if (token != null) {
4071 pos = reAddAppWindowsLocked(pos, token);
4072 }
4073 }
4074
Dianne Hackborna8f60182009-09-01 19:01:50 -07004075 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4076 assignLayersLocked();
4077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 mLayoutNeeded = true;
4079 performLayoutAndPlaceSurfacesLocked();
4080
4081 //dump();
4082 }
4083
4084 public void moveAppTokensToTop(List<IBinder> tokens) {
4085 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4086 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004087 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 }
4089
4090 final long origId = Binder.clearCallingIdentity();
4091 synchronized(mWindowMap) {
4092 removeAppTokensLocked(tokens);
4093 final int N = tokens.size();
4094 for (int i=0; i<N; i++) {
4095 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4096 if (wt != null) {
4097 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004098 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004099 mToTopApps.remove(wt);
4100 mToBottomApps.remove(wt);
4101 mToTopApps.add(wt);
4102 wt.sendingToBottom = false;
4103 wt.sendingToTop = true;
4104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 }
4106 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004107
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004108 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004109 moveAppWindowsLocked(tokens, mAppTokens.size());
4110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 }
4112 Binder.restoreCallingIdentity(origId);
4113 }
4114
4115 public void moveAppTokensToBottom(List<IBinder> tokens) {
4116 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4117 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004118 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 }
4120
4121 final long origId = Binder.clearCallingIdentity();
4122 synchronized(mWindowMap) {
4123 removeAppTokensLocked(tokens);
4124 final int N = tokens.size();
4125 int pos = 0;
4126 for (int i=0; i<N; i++) {
4127 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4128 if (wt != null) {
4129 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004130 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004131 mToTopApps.remove(wt);
4132 mToBottomApps.remove(wt);
4133 mToBottomApps.add(i, wt);
4134 wt.sendingToTop = false;
4135 wt.sendingToBottom = true;
4136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 pos++;
4138 }
4139 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004140
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004141 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004142 moveAppWindowsLocked(tokens, 0);
4143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 }
4145 Binder.restoreCallingIdentity(origId);
4146 }
4147
4148 // -------------------------------------------------------------
4149 // Misc IWindowSession methods
4150 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004151
Jim Miller284b62e2010-06-08 14:27:42 -07004152 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004153 {
Jim Miller284b62e2010-06-08 14:27:42 -07004154 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4155 // called before DevicePolicyManagerService has started.
4156 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4157 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4158 Context.DEVICE_POLICY_SERVICE);
4159 if (dpm != null) {
4160 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4161 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4162 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4163 }
Jim Millerd6b57052010-06-07 17:52:42 -07004164 }
Jim Miller284b62e2010-06-08 14:27:42 -07004165 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004166 }
4167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004169 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 != PackageManager.PERMISSION_GRANTED) {
4171 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4172 }
Jim Millerd6b57052010-06-07 17:52:42 -07004173
Jim Miller284b62e2010-06-08 14:27:42 -07004174 synchronized (mKeyguardTokenWatcher) {
4175 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004177 }
4178
4179 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004180 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 != PackageManager.PERMISSION_GRANTED) {
4182 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184
Jim Miller284b62e2010-06-08 14:27:42 -07004185 synchronized (mKeyguardTokenWatcher) {
4186 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004187
Jim Miller284b62e2010-06-08 14:27:42 -07004188 if (!mKeyguardTokenWatcher.isAcquired()) {
4189 // If we are the last one to reenable the keyguard wait until
4190 // we have actually finished reenabling until returning.
4191 // It is possible that reenableKeyguard() can be called before
4192 // the previous disableKeyguard() is handled, in which case
4193 // neither mKeyguardTokenWatcher.acquired() or released() would
4194 // be called. In that case mKeyguardDisabled will be false here
4195 // and we have nothing to wait for.
4196 while (mKeyguardDisabled) {
4197 try {
4198 mKeyguardTokenWatcher.wait();
4199 } catch (InterruptedException e) {
4200 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 }
4202 }
4203 }
4204 }
4205 }
4206
4207 /**
4208 * @see android.app.KeyguardManager#exitKeyguardSecurely
4209 */
4210 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004211 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 != PackageManager.PERMISSION_GRANTED) {
4213 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4214 }
4215 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4216 public void onKeyguardExitResult(boolean success) {
4217 try {
4218 callback.onKeyguardExitResult(success);
4219 } catch (RemoteException e) {
4220 // Client has died, we don't care.
4221 }
4222 }
4223 });
4224 }
4225
4226 public boolean inKeyguardRestrictedInputMode() {
4227 return mPolicy.inKeyguardRestrictedKeyInputMode();
4228 }
Romain Guy06882f82009-06-10 13:36:04 -07004229
Dianne Hackbornffa42482009-09-23 22:20:11 -07004230 public void closeSystemDialogs(String reason) {
4231 synchronized(mWindowMap) {
4232 for (int i=mWindows.size()-1; i>=0; i--) {
4233 WindowState w = (WindowState)mWindows.get(i);
4234 if (w.mSurface != null) {
4235 try {
4236 w.mClient.closeSystemDialogs(reason);
4237 } catch (RemoteException e) {
4238 }
4239 }
4240 }
4241 }
4242 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 static float fixScale(float scale) {
4245 if (scale < 0) scale = 0;
4246 else if (scale > 20) scale = 20;
4247 return Math.abs(scale);
4248 }
Romain Guy06882f82009-06-10 13:36:04 -07004249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 public void setAnimationScale(int which, float scale) {
4251 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4252 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004253 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 }
4255
4256 if (scale < 0) scale = 0;
4257 else if (scale > 20) scale = 20;
4258 scale = Math.abs(scale);
4259 switch (which) {
4260 case 0: mWindowAnimationScale = fixScale(scale); break;
4261 case 1: mTransitionAnimationScale = fixScale(scale); break;
4262 }
Romain Guy06882f82009-06-10 13:36:04 -07004263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 // Persist setting
4265 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4266 }
Romain Guy06882f82009-06-10 13:36:04 -07004267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 public void setAnimationScales(float[] scales) {
4269 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4270 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004271 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 }
4273
4274 if (scales != null) {
4275 if (scales.length >= 1) {
4276 mWindowAnimationScale = fixScale(scales[0]);
4277 }
4278 if (scales.length >= 2) {
4279 mTransitionAnimationScale = fixScale(scales[1]);
4280 }
4281 }
Romain Guy06882f82009-06-10 13:36:04 -07004282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 // Persist setting
4284 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4285 }
Romain Guy06882f82009-06-10 13:36:04 -07004286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 public float getAnimationScale(int which) {
4288 switch (which) {
4289 case 0: return mWindowAnimationScale;
4290 case 1: return mTransitionAnimationScale;
4291 }
4292 return 0;
4293 }
Romain Guy06882f82009-06-10 13:36:04 -07004294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 public float[] getAnimationScales() {
4296 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4297 }
Romain Guy06882f82009-06-10 13:36:04 -07004298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 public int getSwitchState(int sw) {
4300 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4301 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004302 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004304 return mInputManager.getSwitchState(sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004305 }
Romain Guy06882f82009-06-10 13:36:04 -07004306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 public int getSwitchStateForDevice(int devid, int sw) {
4308 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4309 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004310 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004311 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004312 return mInputManager.getSwitchState(devid, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 }
Romain Guy06882f82009-06-10 13:36:04 -07004314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 public int getScancodeState(int sw) {
4316 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4317 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004318 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004320 return mInputManager.getScancodeState(sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
Romain Guy06882f82009-06-10 13:36:04 -07004322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 public int getScancodeStateForDevice(int devid, int sw) {
4324 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4325 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004326 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004328 return mInputManager.getScancodeState(devid, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 }
Romain Guy06882f82009-06-10 13:36:04 -07004330
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004331 public int getTrackballScancodeState(int sw) {
4332 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4333 "getTrackballScancodeState()")) {
4334 throw new SecurityException("Requires READ_INPUT_STATE permission");
4335 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004336 return mInputManager.getTrackballScancodeState(sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004337 }
4338
4339 public int getDPadScancodeState(int sw) {
4340 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4341 "getDPadScancodeState()")) {
4342 throw new SecurityException("Requires READ_INPUT_STATE permission");
4343 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004344 return mInputManager.getDPadScancodeState(sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004345 }
4346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 public int getKeycodeState(int sw) {
4348 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4349 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004350 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004352 return mInputManager.getKeycodeState(sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 }
Romain Guy06882f82009-06-10 13:36:04 -07004354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 public int getKeycodeStateForDevice(int devid, int sw) {
4356 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4357 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004358 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004360 return mInputManager.getKeycodeState(devid, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 }
Romain Guy06882f82009-06-10 13:36:04 -07004362
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004363 public int getTrackballKeycodeState(int sw) {
4364 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4365 "getTrackballKeycodeState()")) {
4366 throw new SecurityException("Requires READ_INPUT_STATE permission");
4367 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004368 return mInputManager.getTrackballKeycodeState(sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004369 }
4370
4371 public int getDPadKeycodeState(int sw) {
4372 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4373 "getDPadKeycodeState()")) {
4374 throw new SecurityException("Requires READ_INPUT_STATE permission");
4375 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004376 return mInputManager.getDPadKeycodeState(sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004377 }
4378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004380 return mInputManager.hasKeys(keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 }
Romain Guy06882f82009-06-10 13:36:04 -07004382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 public void enableScreenAfterBoot() {
4384 synchronized(mWindowMap) {
4385 if (mSystemBooted) {
4386 return;
4387 }
4388 mSystemBooted = true;
4389 }
Romain Guy06882f82009-06-10 13:36:04 -07004390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 performEnableScreen();
4392 }
Romain Guy06882f82009-06-10 13:36:04 -07004393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004394 public void enableScreenIfNeededLocked() {
4395 if (mDisplayEnabled) {
4396 return;
4397 }
4398 if (!mSystemBooted) {
4399 return;
4400 }
4401 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4402 }
Romain Guy06882f82009-06-10 13:36:04 -07004403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 public void performEnableScreen() {
4405 synchronized(mWindowMap) {
4406 if (mDisplayEnabled) {
4407 return;
4408 }
4409 if (!mSystemBooted) {
4410 return;
4411 }
Romain Guy06882f82009-06-10 13:36:04 -07004412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 // Don't enable the screen until all existing windows
4414 // have been drawn.
4415 final int N = mWindows.size();
4416 for (int i=0; i<N; i++) {
4417 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn5943c202010-04-12 21:36:49 -07004418 if (w.isVisibleLw() && !w.mObscured
4419 && (w.mOrientationChanging || !w.isDrawnLw())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 return;
4421 }
4422 }
Romain Guy06882f82009-06-10 13:36:04 -07004423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 mDisplayEnabled = true;
4425 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004426 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 StringWriter sw = new StringWriter();
4428 PrintWriter pw = new PrintWriter(sw);
4429 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004430 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 }
4432 try {
4433 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4434 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004435 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 Parcel data = Parcel.obtain();
4437 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4438 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4439 data, null, 0);
4440 data.recycle();
4441 }
4442 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004443 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 }
4445 }
Romain Guy06882f82009-06-10 13:36:04 -07004446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004450 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4451 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 }
Romain Guy06882f82009-06-10 13:36:04 -07004453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 public void setInTouchMode(boolean mode) {
4455 synchronized(mWindowMap) {
4456 mInTouchMode = mode;
4457 }
4458 }
4459
Romain Guy06882f82009-06-10 13:36:04 -07004460 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004461 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004463 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004464 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
4466
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004467 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 }
Romain Guy06882f82009-06-10 13:36:04 -07004469
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004470 public void setRotationUnchecked(int rotation,
4471 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004472 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 long origId = Binder.clearCallingIdentity();
4476 boolean changed;
4477 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004478 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 }
Romain Guy06882f82009-06-10 13:36:04 -07004480
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004481 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 sendNewConfiguration();
4483 }
Romain Guy06882f82009-06-10 13:36:04 -07004484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 Binder.restoreCallingIdentity(origId);
4486 }
Romain Guy06882f82009-06-10 13:36:04 -07004487
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004488 /**
4489 * Apply a new rotation to the screen, respecting the requests of
4490 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4491 * re-evaluate the desired rotation.
4492 *
4493 * Returns null if the rotation has been changed. In this case YOU
4494 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4495 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004496 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 boolean changed;
4498 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4499 rotation = mRequestedRotation;
4500 } else {
4501 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004502 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004504 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004505 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004507 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004511 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 "Rotation changed to " + rotation
4513 + " from " + mRotation
4514 + " (forceApp=" + mForcedAppOrientation
4515 + ", req=" + mRequestedRotation + ")");
4516 mRotation = rotation;
4517 mWindowsFreezingScreen = true;
4518 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4519 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4520 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004521 mWaitingForConfig = true;
4522 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004524 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004525 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004527 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004528 }
4529 for (int i=mWindows.size()-1; i>=0; i--) {
4530 WindowState w = (WindowState)mWindows.get(i);
4531 if (w.mSurface != null) {
4532 w.mOrientationChanging = true;
4533 }
4534 }
4535 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4536 try {
4537 mRotationWatchers.get(i).onRotationChanged(rotation);
4538 } catch (RemoteException e) {
4539 }
4540 }
4541 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 return changed;
4544 }
Romain Guy06882f82009-06-10 13:36:04 -07004545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004546 public int getRotation() {
4547 return mRotation;
4548 }
4549
4550 public int watchRotation(IRotationWatcher watcher) {
4551 final IBinder watcherBinder = watcher.asBinder();
4552 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4553 public void binderDied() {
4554 synchronized (mWindowMap) {
4555 for (int i=0; i<mRotationWatchers.size(); i++) {
4556 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004557 IRotationWatcher removed = mRotationWatchers.remove(i);
4558 if (removed != null) {
4559 removed.asBinder().unlinkToDeath(this, 0);
4560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 i--;
4562 }
4563 }
4564 }
4565 }
4566 };
Romain Guy06882f82009-06-10 13:36:04 -07004567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 synchronized (mWindowMap) {
4569 try {
4570 watcher.asBinder().linkToDeath(dr, 0);
4571 mRotationWatchers.add(watcher);
4572 } catch (RemoteException e) {
4573 // Client died, no cleanup needed.
4574 }
Romain Guy06882f82009-06-10 13:36:04 -07004575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 return mRotation;
4577 }
4578 }
4579
4580 /**
4581 * Starts the view server on the specified port.
4582 *
4583 * @param port The port to listener to.
4584 *
4585 * @return True if the server was successfully started, false otherwise.
4586 *
4587 * @see com.android.server.ViewServer
4588 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4589 */
4590 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004591 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 return false;
4593 }
4594
4595 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4596 return false;
4597 }
4598
4599 if (port < 1024) {
4600 return false;
4601 }
4602
4603 if (mViewServer != null) {
4604 if (!mViewServer.isRunning()) {
4605 try {
4606 return mViewServer.start();
4607 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004608 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
4610 }
4611 return false;
4612 }
4613
4614 try {
4615 mViewServer = new ViewServer(this, port);
4616 return mViewServer.start();
4617 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004618 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 }
4620 return false;
4621 }
4622
Romain Guy06882f82009-06-10 13:36:04 -07004623 private boolean isSystemSecure() {
4624 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4625 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4626 }
4627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 /**
4629 * Stops the view server if it exists.
4630 *
4631 * @return True if the server stopped, false if it wasn't started or
4632 * couldn't be stopped.
4633 *
4634 * @see com.android.server.ViewServer
4635 */
4636 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004637 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 return false;
4639 }
4640
4641 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4642 return false;
4643 }
4644
4645 if (mViewServer != null) {
4646 return mViewServer.stop();
4647 }
4648 return false;
4649 }
4650
4651 /**
4652 * Indicates whether the view server is running.
4653 *
4654 * @return True if the server is running, false otherwise.
4655 *
4656 * @see com.android.server.ViewServer
4657 */
4658 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004659 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 return false;
4661 }
4662
4663 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4664 return false;
4665 }
4666
4667 return mViewServer != null && mViewServer.isRunning();
4668 }
4669
4670 /**
4671 * Lists all availble windows in the system. The listing is written in the
4672 * specified Socket's output stream with the following syntax:
4673 * windowHashCodeInHexadecimal windowName
4674 * Each line of the ouput represents a different window.
4675 *
4676 * @param client The remote client to send the listing to.
4677 * @return False if an error occured, true otherwise.
4678 */
4679 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004680 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 return false;
4682 }
4683
4684 boolean result = true;
4685
4686 Object[] windows;
4687 synchronized (mWindowMap) {
4688 windows = new Object[mWindows.size()];
4689 //noinspection unchecked
4690 windows = mWindows.toArray(windows);
4691 }
4692
4693 BufferedWriter out = null;
4694
4695 // Any uncaught exception will crash the system process
4696 try {
4697 OutputStream clientStream = client.getOutputStream();
4698 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4699
4700 final int count = windows.length;
4701 for (int i = 0; i < count; i++) {
4702 final WindowState w = (WindowState) windows[i];
4703 out.write(Integer.toHexString(System.identityHashCode(w)));
4704 out.write(' ');
4705 out.append(w.mAttrs.getTitle());
4706 out.write('\n');
4707 }
4708
4709 out.write("DONE.\n");
4710 out.flush();
4711 } catch (Exception e) {
4712 result = false;
4713 } finally {
4714 if (out != null) {
4715 try {
4716 out.close();
4717 } catch (IOException e) {
4718 result = false;
4719 }
4720 }
4721 }
4722
4723 return result;
4724 }
4725
4726 /**
4727 * Sends a command to a target window. The result of the command, if any, will be
4728 * written in the output stream of the specified socket.
4729 *
4730 * The parameters must follow this syntax:
4731 * windowHashcode extra
4732 *
4733 * Where XX is the length in characeters of the windowTitle.
4734 *
4735 * The first parameter is the target window. The window with the specified hashcode
4736 * will be the target. If no target can be found, nothing happens. The extra parameters
4737 * will be delivered to the target window and as parameters to the command itself.
4738 *
4739 * @param client The remote client to sent the result, if any, to.
4740 * @param command The command to execute.
4741 * @param parameters The command parameters.
4742 *
4743 * @return True if the command was successfully delivered, false otherwise. This does
4744 * not indicate whether the command itself was successful.
4745 */
4746 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004747 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 return false;
4749 }
4750
4751 boolean success = true;
4752 Parcel data = null;
4753 Parcel reply = null;
4754
4755 // Any uncaught exception will crash the system process
4756 try {
4757 // Find the hashcode of the window
4758 int index = parameters.indexOf(' ');
4759 if (index == -1) {
4760 index = parameters.length();
4761 }
4762 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004763 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764
4765 // Extract the command's parameter after the window description
4766 if (index < parameters.length()) {
4767 parameters = parameters.substring(index + 1);
4768 } else {
4769 parameters = "";
4770 }
4771
4772 final WindowManagerService.WindowState window = findWindow(hashCode);
4773 if (window == null) {
4774 return false;
4775 }
4776
4777 data = Parcel.obtain();
4778 data.writeInterfaceToken("android.view.IWindow");
4779 data.writeString(command);
4780 data.writeString(parameters);
4781 data.writeInt(1);
4782 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4783
4784 reply = Parcel.obtain();
4785
4786 final IBinder binder = window.mClient.asBinder();
4787 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4788 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4789
4790 reply.readException();
4791
4792 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004793 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 success = false;
4795 } finally {
4796 if (data != null) {
4797 data.recycle();
4798 }
4799 if (reply != null) {
4800 reply.recycle();
4801 }
4802 }
4803
4804 return success;
4805 }
4806
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004807 public void addWindowChangeListener(WindowChangeListener listener) {
4808 synchronized(mWindowMap) {
4809 mWindowChangeListeners.add(listener);
4810 }
4811 }
4812
4813 public void removeWindowChangeListener(WindowChangeListener listener) {
4814 synchronized(mWindowMap) {
4815 mWindowChangeListeners.remove(listener);
4816 }
4817 }
4818
4819 private void notifyWindowsChanged() {
4820 WindowChangeListener[] windowChangeListeners;
4821 synchronized(mWindowMap) {
4822 if(mWindowChangeListeners.isEmpty()) {
4823 return;
4824 }
4825 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
4826 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
4827 }
4828 int N = windowChangeListeners.length;
4829 for(int i = 0; i < N; i++) {
4830 windowChangeListeners[i].windowsChanged();
4831 }
4832 }
4833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 private WindowState findWindow(int hashCode) {
4835 if (hashCode == -1) {
4836 return getFocusedWindow();
4837 }
4838
4839 synchronized (mWindowMap) {
4840 final ArrayList windows = mWindows;
4841 final int count = windows.size();
4842
4843 for (int i = 0; i < count; i++) {
4844 WindowState w = (WindowState) windows.get(i);
4845 if (System.identityHashCode(w) == hashCode) {
4846 return w;
4847 }
4848 }
4849 }
4850
4851 return null;
4852 }
4853
4854 /*
4855 * Instruct the Activity Manager to fetch the current configuration and broadcast
4856 * that to config-changed listeners if appropriate.
4857 */
4858 void sendNewConfiguration() {
4859 try {
4860 mActivityManager.updateConfiguration(null);
4861 } catch (RemoteException e) {
4862 }
4863 }
Romain Guy06882f82009-06-10 13:36:04 -07004864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004865 public Configuration computeNewConfiguration() {
4866 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07004867 return computeNewConfigurationLocked();
4868 }
4869 }
Romain Guy06882f82009-06-10 13:36:04 -07004870
Dianne Hackbornc485a602009-03-24 22:39:49 -07004871 Configuration computeNewConfigurationLocked() {
4872 Configuration config = new Configuration();
4873 if (!computeNewConfigurationLocked(config)) {
4874 return null;
4875 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07004876 return config;
4877 }
Romain Guy06882f82009-06-10 13:36:04 -07004878
Dianne Hackbornc485a602009-03-24 22:39:49 -07004879 boolean computeNewConfigurationLocked(Configuration config) {
4880 if (mDisplay == null) {
4881 return false;
4882 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004883
4884 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07004885
4886 // Use the effective "visual" dimensions based on current rotation
4887 final boolean rotated = (mRotation == Surface.ROTATION_90
4888 || mRotation == Surface.ROTATION_270);
4889 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
4890 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
4891
Dianne Hackbornc485a602009-03-24 22:39:49 -07004892 int orientation = Configuration.ORIENTATION_SQUARE;
4893 if (dw < dh) {
4894 orientation = Configuration.ORIENTATION_PORTRAIT;
4895 } else if (dw > dh) {
4896 orientation = Configuration.ORIENTATION_LANDSCAPE;
4897 }
4898 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004899
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07004900 DisplayMetrics dm = new DisplayMetrics();
4901 mDisplay.getMetrics(dm);
4902 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
4903
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004904 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07004905 // Note we only do this once because at this point we don't
4906 // expect the screen to change in this way at runtime, and want
4907 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07004908 int longSize = dw;
4909 int shortSize = dh;
4910 if (longSize < shortSize) {
4911 int tmp = longSize;
4912 longSize = shortSize;
4913 shortSize = tmp;
4914 }
4915 longSize = (int)(longSize/dm.density);
4916 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07004917
Dianne Hackborn723738c2009-06-25 19:48:04 -07004918 // These semi-magic numbers define our compatibility modes for
4919 // applications with different screens. Don't change unless you
4920 // make sure to test lots and lots of apps!
4921 if (longSize < 470) {
4922 // This is shorter than an HVGA normal density screen (which
4923 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004924 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
4925 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07004926 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07004927 // What size is this screen screen?
4928 if (longSize >= 800 && shortSize >= 600) {
4929 // SVGA or larger screens at medium density are the point
4930 // at which we consider it to be an extra large screen.
4931 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
4932 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004933 // VGA or larger screens at medium density are the point
4934 // at which we consider it to be a large screen.
4935 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
4936 } else {
4937 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004938
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004939 // If this screen is wider than normal HVGA, or taller
4940 // than FWVGA, then for old apps we want to run in size
4941 // compatibility mode.
4942 if (shortSize > 321 || longSize > 570) {
4943 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
4944 }
4945 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004946
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004947 // Is this a long screen?
4948 if (((longSize*3)/5) >= (shortSize-1)) {
4949 // Anything wider than WVGA (5:3) is considering to be long.
4950 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
4951 } else {
4952 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
4953 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07004954 }
4955 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004956 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004957
Dianne Hackbornc485a602009-03-24 22:39:49 -07004958 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
4959 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
4960 mPolicy.adjustConfigurationLw(config);
4961 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07004963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 // -------------------------------------------------------------
4965 // Input Events and Focus Management
4966 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004967
Jeff Brown349703e2010-06-22 01:27:15 -07004968 InputMonitor mInputMonitor = new InputMonitor();
4969
4970 /* Tracks the progress of input dispatch and ensures that input dispatch state
4971 * is kept in sync with changes in window focus, visibility, registration, and
4972 * other relevant Window Manager state transitions. */
4973 final class InputMonitor {
4974 // Current window with input focus for keys and other non-touch events. May be null.
4975 private WindowState mInputFocus;
4976
4977 // When true, prevents input dispatch from proceeding until set to false again.
4978 private boolean mInputDispatchFrozen;
4979
4980 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
4981 private boolean mInputDispatchEnabled = true;
4982
4983 // Temporary list of windows information to provide to the input dispatcher.
4984 private InputWindowList mTempInputWindows = new InputWindowList();
4985
4986 // Temporary input application object to provide to the input dispatcher.
4987 private InputApplication mTempInputApplication = new InputApplication();
4988
4989 /* Notifies the window manager about a broken input channel.
4990 *
4991 * Called by the InputManager.
4992 */
4993 public void notifyInputChannelBroken(InputChannel inputChannel) {
4994 synchronized (mWindowMap) {
4995 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
4996 if (windowState == null) {
4997 return; // irrelevant
4998 }
4999
5000 Slog.i(TAG, "WINDOW DIED " + windowState);
5001 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005002 }
5003 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005004
Jeff Brown349703e2010-06-22 01:27:15 -07005005 /* Notifies the window manager about an input channel that is not responding.
5006 * The method can either cause dispatching to be aborted by returning -2 or
5007 * return a new timeout in nanoseconds.
5008 *
5009 * Called by the InputManager.
5010 */
5011 public long notifyInputChannelANR(InputChannel inputChannel) {
5012 AppWindowToken token;
5013 synchronized (mWindowMap) {
5014 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5015 if (windowState == null) {
5016 return -2; // irrelevant, abort dispatching (-2)
5017 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005018
Jeff Brown349703e2010-06-22 01:27:15 -07005019 Slog.i(TAG, "Input event dispatching timed out sending to "
5020 + windowState.mAttrs.getTitle());
5021 token = windowState.mAppToken;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005022 }
5023
Jeff Brown349703e2010-06-22 01:27:15 -07005024 return notifyANRInternal(token);
5025 }
5026
5027 /* Notifies the window manager about an input channel spontaneously recovering from ANR
5028 * by successfully delivering the event that originally timed out.
5029 *
5030 * Called by the InputManager.
5031 */
5032 public void notifyInputChannelRecoveredFromANR(InputChannel inputChannel) {
5033 // Nothing to do just now.
5034 // Just wait for the user to dismiss the ANR dialog.
5035 }
5036
5037 /* Notifies the window manager about an application that is not responding
5038 * in general rather than with respect to a particular input channel.
5039 * The method can either cause dispatching to be aborted by returning -2 or
5040 * return a new timeout in nanoseconds.
5041 *
5042 * Called by the InputManager.
5043 */
5044 public long notifyANR(Object token) {
5045 AppWindowToken appWindowToken = (AppWindowToken) token;
5046
5047 Slog.i(TAG, "Input event dispatching timed out sending to application "
5048 + appWindowToken.stringName);
5049 return notifyANRInternal(appWindowToken);
5050 }
5051
5052 private long notifyANRInternal(AppWindowToken token) {
5053 if (token != null && token.appToken != null) {
5054 try {
5055 // Notify the activity manager about the timeout and let it decide whether
5056 // to abort dispatching or keep waiting.
5057 boolean abort = token.appToken.keyDispatchingTimedOut();
5058 if (! abort) {
5059 // The activity manager declined to abort dispatching.
5060 // Wait a bit longer and timeout again later.
5061 return token.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005062 }
Jeff Brown349703e2010-06-22 01:27:15 -07005063 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005064 }
5065 }
Jeff Brown349703e2010-06-22 01:27:15 -07005066 return -2; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005067 }
5068
Jeff Brown349703e2010-06-22 01:27:15 -07005069 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5070 synchronized (mWindowMap) {
5071 return getWindowStateForInputChannelLocked(inputChannel);
5072 }
5073 }
5074
5075 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5076 int windowCount = mWindows.size();
5077 for (int i = 0; i < windowCount; i++) {
5078 WindowState windowState = (WindowState) mWindows.get(i);
5079 if (windowState.mInputChannel == inputChannel) {
5080 return windowState;
5081 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005082 }
5083
Jeff Brown349703e2010-06-22 01:27:15 -07005084 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005085 }
5086
Jeff Brown349703e2010-06-22 01:27:15 -07005087 /* Updates the cached window information provided to the input dispatcher. */
5088 public void updateInputWindowsLw() {
5089 // Populate the input window list with information about all of the windows that
5090 // could potentially receive input.
5091 // As an optimization, we could try to prune the list of windows but this turns
5092 // out to be difficult because only the native code knows for sure which window
5093 // currently has touch focus.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005094 final ArrayList windows = mWindows;
5095 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005096 for (int i = N - 1; i >= 0; i--) {
5097 final WindowState child = (WindowState) windows.get(i);
5098 if (child.mInputChannel == null) {
5099 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005100 continue;
5101 }
5102
Jeff Brown349703e2010-06-22 01:27:15 -07005103 final int flags = child.mAttrs.flags;
5104 final int type = child.mAttrs.type;
5105
5106 final boolean hasFocus = (child == mInputFocus);
5107 final boolean isVisible = child.isVisibleLw();
5108 final boolean hasWallpaper = (child == mWallpaperTarget)
5109 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
5110
5111 // Add a window to our list of input windows.
5112 final InputWindow inputWindow = mTempInputWindows.add();
5113 inputWindow.inputChannel = child.mInputChannel;
5114 inputWindow.layoutParamsFlags = flags;
5115 inputWindow.layoutParamsType = type;
5116 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5117 inputWindow.visible = isVisible;
5118 inputWindow.hasFocus = hasFocus;
5119 inputWindow.hasWallpaper = hasWallpaper;
5120 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
5121 inputWindow.ownerPid = child.mSession.mPid;
5122 inputWindow.ownerUid = child.mSession.mUid;
5123
5124 final Rect frame = child.mFrame;
5125 inputWindow.frameLeft = frame.left;
5126 inputWindow.frameTop = frame.top;
5127
5128 switch (child.mTouchableInsets) {
5129 default:
5130 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5131 inputWindow.touchableAreaLeft = frame.left;
5132 inputWindow.touchableAreaTop = frame.top;
5133 inputWindow.touchableAreaRight = frame.right;
5134 inputWindow.touchableAreaBottom = frame.bottom;
5135 break;
5136
5137 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5138 Rect inset = child.mGivenContentInsets;
5139 inputWindow.touchableAreaLeft = frame.left + inset.left;
5140 inputWindow.touchableAreaTop = frame.top + inset.top;
5141 inputWindow.touchableAreaRight = frame.right - inset.right;
5142 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5143 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005144 }
Jeff Brown349703e2010-06-22 01:27:15 -07005145
5146 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5147 Rect inset = child.mGivenVisibleInsets;
5148 inputWindow.touchableAreaLeft = frame.left + inset.left;
5149 inputWindow.touchableAreaTop = frame.top + inset.top;
5150 inputWindow.touchableAreaRight = frame.right - inset.right;
5151 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005152 break;
5153 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005154 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005155 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005156
Jeff Brown349703e2010-06-22 01:27:15 -07005157 // Send windows to native code.
5158 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005159
Jeff Brown349703e2010-06-22 01:27:15 -07005160 // Clear the list in preparation for the next round.
5161 // Also avoids keeping InputChannel objects referenced unnecessarily.
5162 mTempInputWindows.clear();
5163 }
5164
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005165 /* Provides feedback for a virtual key down. */
5166 public void virtualKeyDownFeedback() {
5167 synchronized (mWindowMap) {
5168 mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
5169 }
5170 }
5171
Jeff Brown349703e2010-06-22 01:27:15 -07005172 /* Notifies that an app switch key (BACK / HOME) has just been pressed.
5173 * This essentially starts a .5 second timeout for the application to process
5174 * subsequent input events while waiting for the app switch to occur. If it takes longer
5175 * than this, the pending events will be dropped.
5176 */
5177 public void notifyAppSwitchComing() {
5178 // TODO Not implemented yet. Should go in the native side.
5179 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005180
5181 /* Notifies that the lid switch changed state. */
5182 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5183 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5184 }
5185
Jeff Brown349703e2010-06-22 01:27:15 -07005186 /* Provides an opportunity for the window manager policy to intercept early key
5187 * processing as soon as the key has been read from the device. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005188 public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
5189 int policyFlags, boolean isScreenOn) {
5190 return mPolicy.interceptKeyBeforeQueueing(whenNanos,
5191 keyCode, down, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005192 }
5193
5194 /* Provides an opportunity for the window manager policy to process a key before
5195 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005196 public boolean interceptKeyBeforeDispatching(InputChannel focus,
5197 int action, int flags, int keyCode, int metaState, int repeatCount,
5198 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005199 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005200 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
5201 keyCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005202 }
5203
5204 /* Called when the current input focus changes.
5205 * Layer assignment is assumed to be complete by the time this is called.
5206 */
5207 public void setInputFocusLw(WindowState newWindow) {
5208 if (DEBUG_INPUT) {
5209 Slog.d(TAG, "Input focus has changed to " + newWindow);
5210 }
5211
5212 if (newWindow != mInputFocus) {
5213 if (newWindow != null && newWindow.canReceiveKeys()) {
5214 // If the new input focus is an error window or appears above the current
5215 // input focus, preempt any pending synchronous dispatch so that we can
5216 // start delivering events to the new input focus as soon as possible.
5217 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
5218 if (DEBUG_INPUT) {
5219 Slog.v(TAG, "New SYSTEM_ERROR window; resetting state");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005220 }
Jeff Brown349703e2010-06-22 01:27:15 -07005221 preemptInputDispatchLw();
5222 } else if (mInputFocus != null && newWindow.mLayer > mInputFocus.mLayer) {
5223 if (DEBUG_INPUT) {
5224 Slog.v(TAG, "Transferring focus to new window at higher layer: "
5225 + "old win layer=" + mInputFocus.mLayer
5226 + ", new win layer=" + newWindow.mLayer);
5227 }
5228 preemptInputDispatchLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005229 }
Jeff Brown349703e2010-06-22 01:27:15 -07005230
5231 // Displaying a window implicitly causes dispatching to be unpaused.
5232 // This is to protect against bugs if someone pauses dispatching but
5233 // forgets to resume.
5234 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005235 }
Jeff Brown349703e2010-06-22 01:27:15 -07005236
5237 mInputFocus = newWindow;
5238 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005239 }
5240 }
5241
Jeff Brown349703e2010-06-22 01:27:15 -07005242 public void windowIsBecomingInvisibleLw(WindowState window) {
5243 // The window is becoming invisible. Preempt input dispatch in progress
5244 // so that the next window below can receive focus.
5245 if (window == mInputFocus) {
5246 mInputFocus = null;
5247 preemptInputDispatchLw();
5248 }
5249
5250 updateInputWindowsLw();
5251 }
5252
5253 /* Tells the dispatcher to stop waiting for its current synchronous event targets.
5254 * Essentially, just makes those dispatches asynchronous so a new dispatch cycle
5255 * can begin.
5256 */
5257 private void preemptInputDispatchLw() {
5258 mInputManager.preemptInputDispatch();
5259 }
5260
5261 public void setFocusedAppLw(AppWindowToken newApp) {
5262 // Focused app has changed.
5263 if (newApp == null) {
5264 mInputManager.setFocusedApplication(null);
5265 } else {
5266 mTempInputApplication.name = newApp.toString();
5267 mTempInputApplication.dispatchingTimeoutNanos =
5268 newApp.inputDispatchingTimeoutNanos;
5269 mTempInputApplication.token = newApp;
5270
5271 mInputManager.setFocusedApplication(mTempInputApplication);
5272 }
5273 }
5274
5275 public void windowIsBeingRemovedLw(WindowState window) {
5276 // Window is being removed.
5277 updateInputWindowsLw();
5278 }
5279
5280 public void pauseDispatchingLw(WindowToken window) {
5281 if (! window.paused) {
5282 if (DEBUG_INPUT) {
5283 Slog.v(TAG, "Pausing WindowToken " + window);
5284 }
5285
5286 window.paused = true;
5287 updateInputWindowsLw();
5288 }
5289 }
5290
5291 public void resumeDispatchingLw(WindowToken window) {
5292 if (window.paused) {
5293 if (DEBUG_INPUT) {
5294 Slog.v(TAG, "Resuming WindowToken " + window);
5295 }
5296
5297 window.paused = false;
5298 updateInputWindowsLw();
5299 }
5300 }
5301
5302 public void freezeInputDispatchingLw() {
5303 if (! mInputDispatchFrozen) {
5304 if (DEBUG_INPUT) {
5305 Slog.v(TAG, "Freezing input dispatching");
5306 }
5307
5308 mInputDispatchFrozen = true;
5309 updateInputDispatchModeLw();
5310 }
5311 }
5312
5313 public void thawInputDispatchingLw() {
5314 if (mInputDispatchFrozen) {
5315 if (DEBUG_INPUT) {
5316 Slog.v(TAG, "Thawing input dispatching");
5317 }
5318
5319 mInputDispatchFrozen = false;
5320 updateInputDispatchModeLw();
5321 }
5322 }
5323
5324 public void setEventDispatchingLw(boolean enabled) {
5325 if (mInputDispatchEnabled != enabled) {
5326 if (DEBUG_INPUT) {
5327 Slog.v(TAG, "Setting event dispatching to " + enabled);
5328 }
5329
5330 mInputDispatchEnabled = enabled;
5331 updateInputDispatchModeLw();
5332 }
5333 }
5334
5335 private void updateInputDispatchModeLw() {
5336 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5337 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005340 public void pauseKeyDispatching(IBinder _token) {
5341 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5342 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005343 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005344 }
5345
5346 synchronized (mWindowMap) {
5347 WindowToken token = mTokenMap.get(_token);
5348 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005349 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 }
5351 }
5352 }
5353
5354 public void resumeKeyDispatching(IBinder _token) {
5355 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5356 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005357 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005358 }
5359
5360 synchronized (mWindowMap) {
5361 WindowToken token = mTokenMap.get(_token);
5362 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005363 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 }
5365 }
5366 }
5367
5368 public void setEventDispatching(boolean enabled) {
5369 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5370 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005371 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 }
5373
5374 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005375 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 }
5377 }
Romain Guy06882f82009-06-10 13:36:04 -07005378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005379 /**
5380 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005381 *
5382 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005383 * {@link SystemClock#uptimeMillis()} as the timebase.)
5384 * @param sync If true, wait for the event to be completed before returning to the caller.
5385 * @return Returns true if event was dispatched, false if it was dropped for any reason
5386 */
5387 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5388 long downTime = ev.getDownTime();
5389 long eventTime = ev.getEventTime();
5390
5391 int action = ev.getAction();
5392 int code = ev.getKeyCode();
5393 int repeatCount = ev.getRepeatCount();
5394 int metaState = ev.getMetaState();
5395 int deviceId = ev.getDeviceId();
5396 int scancode = ev.getScanCode();
5397
5398 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5399 if (downTime == 0) downTime = eventTime;
5400
5401 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07005402 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005403
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005404 final int pid = Binder.getCallingPid();
5405 final int uid = Binder.getCallingUid();
5406 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005407
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005408 final int result = mInputManager.injectKeyEvent(newEvent,
5409 InputQueue.INPUT_EVENT_NATURE_KEY, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005410
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005411 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005412 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005413 }
5414
5415 /**
5416 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005417 *
5418 * @param ev A motion event describing the pointer (touch) action. (As noted in
5419 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 * {@link SystemClock#uptimeMillis()} as the timebase.)
5421 * @param sync If true, wait for the event to be completed before returning to the caller.
5422 * @return Returns true if event was dispatched, false if it was dropped for any reason
5423 */
5424 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005425 final int pid = Binder.getCallingPid();
5426 final int uid = Binder.getCallingUid();
5427 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005428
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005429 final int result = mInputManager.injectMotionEvent(ev,
5430 InputQueue.INPUT_EVENT_NATURE_TOUCH, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005431
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005432 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005433 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 }
Romain Guy06882f82009-06-10 13:36:04 -07005435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 /**
5437 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005438 *
5439 * @param ev A motion event describing the trackball action. (As noted in
5440 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 * {@link SystemClock#uptimeMillis()} as the timebase.)
5442 * @param sync If true, wait for the event to be completed before returning to the caller.
5443 * @return Returns true if event was dispatched, false if it was dropped for any reason
5444 */
5445 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005446 final int pid = Binder.getCallingPid();
5447 final int uid = Binder.getCallingUid();
5448 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005449
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005450 final int result = mInputManager.injectMotionEvent(ev,
5451 InputQueue.INPUT_EVENT_NATURE_TRACKBALL, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005452
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005453 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005454 return reportInjectionResult(result);
5455 }
5456
5457 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005458 switch (result) {
5459 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5460 Slog.w(TAG, "Input event injection permission denied.");
5461 throw new SecurityException(
5462 "Injecting to another application requires INJECT_EVENTS permission");
5463 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
5464 Slog.v(TAG, "Input event injection succeeded.");
5465 return true;
5466 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5467 Slog.w(TAG, "Input event injection timed out.");
5468 return false;
5469 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5470 default:
5471 Slog.w(TAG, "Input event injection failed.");
5472 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 }
Romain Guy06882f82009-06-10 13:36:04 -07005475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 private WindowState getFocusedWindow() {
5477 synchronized (mWindowMap) {
5478 return getFocusedWindowLocked();
5479 }
5480 }
5481
5482 private WindowState getFocusedWindowLocked() {
5483 return mCurrentFocus;
5484 }
Romain Guy06882f82009-06-10 13:36:04 -07005485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 public boolean detectSafeMode() {
5487 mSafeMode = mPolicy.detectSafeMode();
5488 return mSafeMode;
5489 }
Romain Guy06882f82009-06-10 13:36:04 -07005490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 public void systemReady() {
5492 mPolicy.systemReady();
5493 }
Romain Guy06882f82009-06-10 13:36:04 -07005494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 // -------------------------------------------------------------
5496 // Client Session State
5497 // -------------------------------------------------------------
5498
5499 private final class Session extends IWindowSession.Stub
5500 implements IBinder.DeathRecipient {
5501 final IInputMethodClient mClient;
5502 final IInputContext mInputContext;
5503 final int mUid;
5504 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005505 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 SurfaceSession mSurfaceSession;
5507 int mNumWindow = 0;
5508 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07005509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 public Session(IInputMethodClient client, IInputContext inputContext) {
5511 mClient = client;
5512 mInputContext = inputContext;
5513 mUid = Binder.getCallingUid();
5514 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005515 StringBuilder sb = new StringBuilder();
5516 sb.append("Session{");
5517 sb.append(Integer.toHexString(System.identityHashCode(this)));
5518 sb.append(" uid ");
5519 sb.append(mUid);
5520 sb.append("}");
5521 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07005522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 synchronized (mWindowMap) {
5524 if (mInputMethodManager == null && mHaveInputMethods) {
5525 IBinder b = ServiceManager.getService(
5526 Context.INPUT_METHOD_SERVICE);
5527 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
5528 }
5529 }
5530 long ident = Binder.clearCallingIdentity();
5531 try {
5532 // Note: it is safe to call in to the input method manager
5533 // here because we are not holding our lock.
5534 if (mInputMethodManager != null) {
5535 mInputMethodManager.addClient(client, inputContext,
5536 mUid, mPid);
5537 } else {
5538 client.setUsingInputMethod(false);
5539 }
5540 client.asBinder().linkToDeath(this, 0);
5541 } catch (RemoteException e) {
5542 // The caller has died, so we can just forget about this.
5543 try {
5544 if (mInputMethodManager != null) {
5545 mInputMethodManager.removeClient(client);
5546 }
5547 } catch (RemoteException ee) {
5548 }
5549 } finally {
5550 Binder.restoreCallingIdentity(ident);
5551 }
5552 }
Romain Guy06882f82009-06-10 13:36:04 -07005553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005554 @Override
5555 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
5556 throws RemoteException {
5557 try {
5558 return super.onTransact(code, data, reply, flags);
5559 } catch (RuntimeException e) {
5560 // Log all 'real' exceptions thrown to the caller
5561 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005562 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 }
5564 throw e;
5565 }
5566 }
5567
5568 public void binderDied() {
5569 // Note: it is safe to call in to the input method manager
5570 // here because we are not holding our lock.
5571 try {
5572 if (mInputMethodManager != null) {
5573 mInputMethodManager.removeClient(mClient);
5574 }
5575 } catch (RemoteException e) {
5576 }
5577 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005578 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 mClientDead = true;
5580 killSessionLocked();
5581 }
5582 }
5583
5584 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005585 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
5586 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
5587 outInputChannel);
5588 }
5589
5590 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005592 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 }
Romain Guy06882f82009-06-10 13:36:04 -07005594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 public void remove(IWindow window) {
5596 removeWindow(this, window);
5597 }
Romain Guy06882f82009-06-10 13:36:04 -07005598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
5600 int requestedWidth, int requestedHeight, int viewFlags,
5601 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07005602 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005603 return relayoutWindow(this, window, attrs,
5604 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07005605 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005606 }
Romain Guy06882f82009-06-10 13:36:04 -07005607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005608 public void setTransparentRegion(IWindow window, Region region) {
5609 setTransparentRegionWindow(this, window, region);
5610 }
Romain Guy06882f82009-06-10 13:36:04 -07005611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 public void setInsets(IWindow window, int touchableInsets,
5613 Rect contentInsets, Rect visibleInsets) {
5614 setInsetsWindow(this, window, touchableInsets, contentInsets,
5615 visibleInsets);
5616 }
Romain Guy06882f82009-06-10 13:36:04 -07005617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
5619 getWindowDisplayFrame(this, window, outDisplayFrame);
5620 }
Romain Guy06882f82009-06-10 13:36:04 -07005621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005623 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 TAG, "IWindow finishDrawing called for " + window);
5625 finishDrawingWindow(this, window);
5626 }
5627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 public void setInTouchMode(boolean mode) {
5629 synchronized(mWindowMap) {
5630 mInTouchMode = mode;
5631 }
5632 }
5633
5634 public boolean getInTouchMode() {
5635 synchronized(mWindowMap) {
5636 return mInTouchMode;
5637 }
5638 }
5639
5640 public boolean performHapticFeedback(IWindow window, int effectId,
5641 boolean always) {
5642 synchronized(mWindowMap) {
5643 long ident = Binder.clearCallingIdentity();
5644 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07005645 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005646 windowForClientLocked(this, window, true),
5647 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005648 } finally {
5649 Binder.restoreCallingIdentity(ident);
5650 }
5651 }
5652 }
Romain Guy06882f82009-06-10 13:36:04 -07005653
Marco Nelissenbf6956b2009-11-09 15:21:13 -08005654 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07005655 synchronized(mWindowMap) {
5656 long ident = Binder.clearCallingIdentity();
5657 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005658 setWindowWallpaperPositionLocked(
5659 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08005660 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07005661 } finally {
5662 Binder.restoreCallingIdentity(ident);
5663 }
5664 }
5665 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005666
Dianne Hackborn19382ac2009-09-11 21:13:37 -07005667 public void wallpaperOffsetsComplete(IBinder window) {
5668 WindowManagerService.this.wallpaperOffsetsComplete(window);
5669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005670
Dianne Hackborn75804932009-10-20 20:15:20 -07005671 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
5672 int z, Bundle extras, boolean sync) {
5673 synchronized(mWindowMap) {
5674 long ident = Binder.clearCallingIdentity();
5675 try {
5676 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005677 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07005678 action, x, y, z, extras, sync);
5679 } finally {
5680 Binder.restoreCallingIdentity(ident);
5681 }
5682 }
5683 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005684
Dianne Hackborn75804932009-10-20 20:15:20 -07005685 public void wallpaperCommandComplete(IBinder window, Bundle result) {
5686 WindowManagerService.this.wallpaperCommandComplete(window, result);
5687 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 void windowAddedLocked() {
5690 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005691 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 TAG, "First window added to " + this + ", creating SurfaceSession");
5693 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005694 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07005695 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 mSessions.add(this);
5697 }
5698 mNumWindow++;
5699 }
5700
5701 void windowRemovedLocked() {
5702 mNumWindow--;
5703 killSessionLocked();
5704 }
Romain Guy06882f82009-06-10 13:36:04 -07005705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 void killSessionLocked() {
5707 if (mNumWindow <= 0 && mClientDead) {
5708 mSessions.remove(this);
5709 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005710 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005711 TAG, "Last window removed from " + this
5712 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005713 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07005714 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 try {
5716 mSurfaceSession.kill();
5717 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005718 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 + mSurfaceSession + " in session " + this
5720 + ": " + e.toString());
5721 }
5722 mSurfaceSession = null;
5723 }
5724 }
5725 }
Romain Guy06882f82009-06-10 13:36:04 -07005726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005727 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005728 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
5729 pw.print(" mClientDead="); pw.print(mClientDead);
5730 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005731 }
5732
5733 @Override
5734 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005735 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 }
5737 }
5738
5739 // -------------------------------------------------------------
5740 // Client Window State
5741 // -------------------------------------------------------------
5742
5743 private final class WindowState implements WindowManagerPolicy.WindowState {
5744 final Session mSession;
5745 final IWindow mClient;
5746 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07005747 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 AppWindowToken mAppToken;
5749 AppWindowToken mTargetAppToken;
5750 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
5751 final DeathRecipient mDeathRecipient;
5752 final WindowState mAttachedWindow;
5753 final ArrayList mChildWindows = new ArrayList();
5754 final int mBaseLayer;
5755 final int mSubLayer;
5756 final boolean mLayoutAttached;
5757 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07005758 final boolean mIsWallpaper;
5759 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 int mViewVisibility;
5761 boolean mPolicyVisibility = true;
5762 boolean mPolicyVisibilityAfterAnim = true;
5763 boolean mAppFreezing;
5764 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07005765 boolean mReportDestroySurface;
5766 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005767 boolean mAttachedHidden; // is our parent window hidden?
5768 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07005769 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005770 int mRequestedWidth;
5771 int mRequestedHeight;
5772 int mLastRequestedWidth;
5773 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 int mLayer;
5775 int mAnimLayer;
5776 int mLastLayer;
5777 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07005778 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07005779 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005780
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005781 int mLayoutSeq = -1;
5782
5783 Configuration mConfiguration = null;
5784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005785 // Actual frame shown on-screen (may be modified by animation)
5786 final Rect mShownFrame = new Rect();
5787 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07005788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005789 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08005790 * Set when we have changed the size of the surface, to know that
5791 * we must tell them application to resize (and thus redraw itself).
5792 */
5793 boolean mSurfaceResized;
5794
5795 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005796 * Insets that determine the actually visible area
5797 */
5798 final Rect mVisibleInsets = new Rect();
5799 final Rect mLastVisibleInsets = new Rect();
5800 boolean mVisibleInsetsChanged;
5801
5802 /**
5803 * Insets that are covered by system windows
5804 */
5805 final Rect mContentInsets = new Rect();
5806 final Rect mLastContentInsets = new Rect();
5807 boolean mContentInsetsChanged;
5808
5809 /**
5810 * Set to true if we are waiting for this window to receive its
5811 * given internal insets before laying out other windows based on it.
5812 */
5813 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07005814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 /**
5816 * These are the content insets that were given during layout for
5817 * this window, to be applied to windows behind it.
5818 */
5819 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07005820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 /**
5822 * These are the visible insets that were given during layout for
5823 * this window, to be applied to windows behind it.
5824 */
5825 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07005826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 /**
5828 * Flag indicating whether the touchable region should be adjusted by
5829 * the visible insets; if false the area outside the visible insets is
5830 * NOT touchable, so we must use those to adjust the frame during hit
5831 * tests.
5832 */
5833 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07005834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005835 // Current transformation being applied.
5836 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
5837 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
5838 float mHScale=1, mVScale=1;
5839 float mLastHScale=1, mLastVScale=1;
5840 final Matrix mTmpMatrix = new Matrix();
5841
5842 // "Real" frame that the application sees.
5843 final Rect mFrame = new Rect();
5844 final Rect mLastFrame = new Rect();
5845
5846 final Rect mContainingFrame = new Rect();
5847 final Rect mDisplayFrame = new Rect();
5848 final Rect mContentFrame = new Rect();
5849 final Rect mVisibleFrame = new Rect();
5850
5851 float mShownAlpha = 1;
5852 float mAlpha = 1;
5853 float mLastAlpha = 1;
5854
5855 // Set to true if, when the window gets displayed, it should perform
5856 // an enter animation.
5857 boolean mEnterAnimationPending;
5858
5859 // Currently running animation.
5860 boolean mAnimating;
5861 boolean mLocalAnimating;
5862 Animation mAnimation;
5863 boolean mAnimationIsEntrance;
5864 boolean mHasTransformation;
5865 boolean mHasLocalTransformation;
5866 final Transformation mTransformation = new Transformation();
5867
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07005868 // If a window showing a wallpaper: the requested offset for the
5869 // wallpaper; if a wallpaper window: the currently applied offset.
5870 float mWallpaperX = -1;
5871 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08005872
5873 // If a window showing a wallpaper: what fraction of the offset
5874 // range corresponds to a full virtual screen.
5875 float mWallpaperXStep = -1;
5876 float mWallpaperYStep = -1;
5877
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07005878 // Wallpaper windows: pixels offset based on above variables.
5879 int mXOffset;
5880 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 // This is set after IWindowSession.relayout() has been called at
5883 // least once for the window. It allows us to detect the situation
5884 // where we don't yet have a surface, but should have one soon, so
5885 // we can give the window focus before waiting for the relayout.
5886 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07005887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 // This is set after the Surface has been created but before the
5889 // window has been drawn. During this time the surface is hidden.
5890 boolean mDrawPending;
5891
5892 // This is set after the window has finished drawing for the first
5893 // time but before its surface is shown. The surface will be
5894 // displayed when the next layout is run.
5895 boolean mCommitDrawPending;
5896
5897 // This is set during the time after the window's drawing has been
5898 // committed, and before its surface is actually shown. It is used
5899 // to delay showing the surface until all windows in a token are ready
5900 // to be shown.
5901 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07005902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 // Set when the window has been shown in the screen the first time.
5904 boolean mHasDrawn;
5905
5906 // Currently running an exit animation?
5907 boolean mExiting;
5908
5909 // Currently on the mDestroySurface list?
5910 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07005911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 // Completely remove from window manager after exit animation?
5913 boolean mRemoveOnExit;
5914
5915 // Set when the orientation is changing and this window has not yet
5916 // been updated for the new orientation.
5917 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07005918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 // Is this window now (or just being) removed?
5920 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07005921
Dianne Hackborn16064f92010-03-25 00:47:24 -07005922 // For debugging, this is the last information given to the surface flinger.
5923 boolean mSurfaceShown;
5924 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
5925 int mSurfaceLayer;
5926 float mSurfaceAlpha;
5927
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005928 // Input channel
5929 InputChannel mInputChannel;
5930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 WindowState(Session s, IWindow c, WindowToken token,
5932 WindowState attachedWindow, WindowManager.LayoutParams a,
5933 int viewVisibility) {
5934 mSession = s;
5935 mClient = c;
5936 mToken = token;
5937 mAttrs.copyFrom(a);
5938 mViewVisibility = viewVisibility;
5939 DeathRecipient deathRecipient = new DeathRecipient();
5940 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005941 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 TAG, "Window " + this + " client=" + c.asBinder()
5943 + " token=" + token + " (" + mAttrs.token + ")");
5944 try {
5945 c.asBinder().linkToDeath(deathRecipient, 0);
5946 } catch (RemoteException e) {
5947 mDeathRecipient = null;
5948 mAttachedWindow = null;
5949 mLayoutAttached = false;
5950 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07005951 mIsWallpaper = false;
5952 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005953 mBaseLayer = 0;
5954 mSubLayer = 0;
5955 return;
5956 }
5957 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07005958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005959 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
5960 mAttrs.type <= LAST_SUB_WINDOW)) {
5961 // The multiplier here is to reserve space for multiple
5962 // windows in the same type layer.
5963 mBaseLayer = mPolicy.windowTypeToLayerLw(
5964 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
5965 + TYPE_LAYER_OFFSET;
5966 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
5967 mAttachedWindow = attachedWindow;
5968 mAttachedWindow.mChildWindows.add(this);
5969 mLayoutAttached = mAttrs.type !=
5970 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
5971 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
5972 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07005973 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
5974 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 } else {
5976 // The multiplier here is to reserve space for multiple
5977 // windows in the same type layer.
5978 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
5979 * TYPE_LAYER_MULTIPLIER
5980 + TYPE_LAYER_OFFSET;
5981 mSubLayer = 0;
5982 mAttachedWindow = null;
5983 mLayoutAttached = false;
5984 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
5985 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07005986 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
5987 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988 }
5989
5990 WindowState appWin = this;
5991 while (appWin.mAttachedWindow != null) {
5992 appWin = mAttachedWindow;
5993 }
5994 WindowToken appToken = appWin.mToken;
5995 while (appToken.appWindowToken == null) {
5996 WindowToken parent = mTokenMap.get(appToken.token);
5997 if (parent == null || appToken == parent) {
5998 break;
5999 }
6000 appToken = parent;
6001 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006002 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 mAppToken = appToken.appWindowToken;
6004
6005 mSurface = null;
6006 mRequestedWidth = 0;
6007 mRequestedHeight = 0;
6008 mLastRequestedWidth = 0;
6009 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006010 mXOffset = 0;
6011 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 mLayer = 0;
6013 mAnimLayer = 0;
6014 mLastLayer = 0;
6015 }
6016
6017 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006018 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 TAG, "Attaching " + this + " token=" + mToken
6020 + ", list=" + mToken.windows);
6021 mSession.windowAddedLocked();
6022 }
6023
6024 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6025 mHaveFrame = true;
6026
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006027 final Rect container = mContainingFrame;
6028 container.set(pf);
6029
6030 final Rect display = mDisplayFrame;
6031 display.set(df);
6032
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006033 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006034 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006035 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6036 display.intersect(mCompatibleScreenFrame);
6037 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006038 }
6039
6040 final int pw = container.right - container.left;
6041 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006042
6043 int w,h;
6044 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6045 w = mAttrs.width < 0 ? pw : mAttrs.width;
6046 h = mAttrs.height< 0 ? ph : mAttrs.height;
6047 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006048 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6049 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006050 }
Romain Guy06882f82009-06-10 13:36:04 -07006051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 final Rect content = mContentFrame;
6053 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 final Rect visible = mVisibleFrame;
6056 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006059 final int fw = frame.width();
6060 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6063 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6064
6065 Gravity.apply(mAttrs.gravity, w, h, container,
6066 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6067 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6068
6069 //System.out.println("Out: " + mFrame);
6070
6071 // Now make sure the window fits in the overall display.
6072 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 // Make sure the content and visible frames are inside of the
6075 // final window frame.
6076 if (content.left < frame.left) content.left = frame.left;
6077 if (content.top < frame.top) content.top = frame.top;
6078 if (content.right > frame.right) content.right = frame.right;
6079 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6080 if (visible.left < frame.left) visible.left = frame.left;
6081 if (visible.top < frame.top) visible.top = frame.top;
6082 if (visible.right > frame.right) visible.right = frame.right;
6083 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 final Rect contentInsets = mContentInsets;
6086 contentInsets.left = content.left-frame.left;
6087 contentInsets.top = content.top-frame.top;
6088 contentInsets.right = frame.right-content.right;
6089 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 final Rect visibleInsets = mVisibleInsets;
6092 visibleInsets.left = visible.left-frame.left;
6093 visibleInsets.top = visible.top-frame.top;
6094 visibleInsets.right = frame.right-visible.right;
6095 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006096
Dianne Hackborn284ac932009-08-28 10:34:25 -07006097 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6098 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006099 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006100 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 if (localLOGV) {
6103 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6104 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006105 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 + mRequestedWidth + ", mRequestedheight="
6107 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6108 + "): frame=" + mFrame.toShortString()
6109 + " ci=" + contentInsets.toShortString()
6110 + " vi=" + visibleInsets.toShortString());
6111 //}
6112 }
6113 }
Romain Guy06882f82009-06-10 13:36:04 -07006114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 public Rect getFrameLw() {
6116 return mFrame;
6117 }
6118
6119 public Rect getShownFrameLw() {
6120 return mShownFrame;
6121 }
6122
6123 public Rect getDisplayFrameLw() {
6124 return mDisplayFrame;
6125 }
6126
6127 public Rect getContentFrameLw() {
6128 return mContentFrame;
6129 }
6130
6131 public Rect getVisibleFrameLw() {
6132 return mVisibleFrame;
6133 }
6134
6135 public boolean getGivenInsetsPendingLw() {
6136 return mGivenInsetsPending;
6137 }
6138
6139 public Rect getGivenContentInsetsLw() {
6140 return mGivenContentInsets;
6141 }
Romain Guy06882f82009-06-10 13:36:04 -07006142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006143 public Rect getGivenVisibleInsetsLw() {
6144 return mGivenVisibleInsets;
6145 }
Romain Guy06882f82009-06-10 13:36:04 -07006146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006147 public WindowManager.LayoutParams getAttrs() {
6148 return mAttrs;
6149 }
6150
6151 public int getSurfaceLayer() {
6152 return mLayer;
6153 }
Romain Guy06882f82009-06-10 13:36:04 -07006154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 public IApplicationToken getAppToken() {
6156 return mAppToken != null ? mAppToken.appToken : null;
6157 }
Jeff Brown349703e2010-06-22 01:27:15 -07006158
6159 public long getInputDispatchingTimeoutNanos() {
6160 return mAppToken != null
6161 ? mAppToken.inputDispatchingTimeoutNanos
6162 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164
6165 public boolean hasAppShownWindows() {
6166 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6167 }
6168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006170 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 TAG, "Setting animation in " + this + ": " + anim);
6172 mAnimating = false;
6173 mLocalAnimating = false;
6174 mAnimation = anim;
6175 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6176 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6177 }
6178
6179 public void clearAnimation() {
6180 if (mAnimation != null) {
6181 mAnimating = true;
6182 mLocalAnimating = false;
6183 mAnimation = null;
6184 }
6185 }
Romain Guy06882f82009-06-10 13:36:04 -07006186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006187 Surface createSurfaceLocked() {
6188 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006189 mReportDestroySurface = false;
6190 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006191 mDrawPending = true;
6192 mCommitDrawPending = false;
6193 mReadyToShow = false;
6194 if (mAppToken != null) {
6195 mAppToken.allDrawn = false;
6196 }
6197
6198 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006199 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006200 flags |= Surface.PUSH_BUFFERS;
6201 }
6202
6203 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6204 flags |= Surface.SECURE;
6205 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006206 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006207 TAG, "Creating surface in session "
6208 + mSession.mSurfaceSession + " window " + this
6209 + " w=" + mFrame.width()
6210 + " h=" + mFrame.height() + " format="
6211 + mAttrs.format + " flags=" + flags);
6212
6213 int w = mFrame.width();
6214 int h = mFrame.height();
6215 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
6216 // for a scaled surface, we always want the requested
6217 // size.
6218 w = mRequestedWidth;
6219 h = mRequestedHeight;
6220 }
6221
Romain Guy9825ec62009-10-01 00:58:09 -07006222 // Something is wrong and SurfaceFlinger will not like this,
6223 // try to revert to sane values
6224 if (w <= 0) w = 1;
6225 if (h <= 0) h = 1;
6226
Dianne Hackborn16064f92010-03-25 00:47:24 -07006227 mSurfaceShown = false;
6228 mSurfaceLayer = 0;
6229 mSurfaceAlpha = 1;
6230 mSurfaceX = 0;
6231 mSurfaceY = 0;
6232 mSurfaceW = w;
6233 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 try {
6235 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07006236 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08006237 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006238 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006239 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006240 + mSurface + " IN SESSION "
6241 + mSession.mSurfaceSession
6242 + ": pid=" + mSession.mPid + " format="
6243 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006244 + Integer.toHexString(flags)
6245 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006246 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006247 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006248 reclaimSomeSurfaceMemoryLocked(this, "create");
6249 return null;
6250 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006251 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006252 return null;
6253 }
Romain Guy06882f82009-06-10 13:36:04 -07006254
Joe Onorato8a9b2202010-02-26 18:56:32 -08006255 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 TAG, "Got surface: " + mSurface
6257 + ", set left=" + mFrame.left + " top=" + mFrame.top
6258 + ", animLayer=" + mAnimLayer);
6259 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006260 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006261 if (SHOW_TRANSACTIONS) logSurface(this,
6262 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
6263 mFrame.width() + "x" + mFrame.height() + "), layer=" +
6264 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 }
6266 Surface.openTransaction();
6267 try {
6268 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07006269 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07006270 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07006271 mSurface.setPosition(mSurfaceX, mSurfaceY);
6272 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006274 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 mSurface.hide();
6276 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006277 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 mSurface.setFlags(Surface.SURFACE_DITHER,
6279 Surface.SURFACE_DITHER);
6280 }
6281 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006282 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 reclaimSomeSurfaceMemoryLocked(this, "create-init");
6284 }
6285 mLastHidden = true;
6286 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006287 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006288 Surface.closeTransaction();
6289 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006290 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 TAG, "Created surface " + this);
6292 }
6293 return mSurface;
6294 }
Romain Guy06882f82009-06-10 13:36:04 -07006295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 if (mAppToken != null && this == mAppToken.startingWindow) {
6298 mAppToken.startingDisplayed = false;
6299 }
Romain Guy06882f82009-06-10 13:36:04 -07006300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006302 mDrawPending = false;
6303 mCommitDrawPending = false;
6304 mReadyToShow = false;
6305
6306 int i = mChildWindows.size();
6307 while (i > 0) {
6308 i--;
6309 WindowState c = (WindowState)mChildWindows.get(i);
6310 c.mAttachedHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07006311
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006312 mInputMonitor.windowIsBecomingInvisibleLw(c);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006313 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006314
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006315 if (mReportDestroySurface) {
6316 mReportDestroySurface = false;
6317 mSurfacePendingDestroy = true;
6318 try {
6319 mClient.dispatchGetNewSurface();
6320 // We'll really destroy on the next time around.
6321 return;
6322 } catch (RemoteException e) {
6323 }
6324 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006326 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006327 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006328 RuntimeException e = null;
6329 if (!HIDE_STACK_CRAWLS) {
6330 e = new RuntimeException();
6331 e.fillInStackTrace();
6332 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006333 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006334 + mSurface + ", session " + mSession, e);
6335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006337 RuntimeException e = null;
6338 if (!HIDE_STACK_CRAWLS) {
6339 e = new RuntimeException();
6340 e.fillInStackTrace();
6341 }
6342 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006343 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006344 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006345 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006346 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006347 + " surface " + mSurface + " session " + mSession
6348 + ": " + e.toString());
6349 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006350
Dianne Hackborn16064f92010-03-25 00:47:24 -07006351 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006352 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006353 }
6354 }
6355
6356 boolean finishDrawingLocked() {
6357 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006358 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 TAG, "finishDrawingLocked: " + mSurface);
6360 mCommitDrawPending = true;
6361 mDrawPending = false;
6362 return true;
6363 }
6364 return false;
6365 }
6366
6367 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006368 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006369 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006371 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 }
6373 mCommitDrawPending = false;
6374 mReadyToShow = true;
6375 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
6376 final AppWindowToken atoken = mAppToken;
6377 if (atoken == null || atoken.allDrawn || starting) {
6378 performShowLocked();
6379 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006380 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 }
6382
6383 // This must be called while inside a transaction.
6384 boolean performShowLocked() {
6385 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006386 RuntimeException e = null;
6387 if (!HIDE_STACK_CRAWLS) {
6388 e = new RuntimeException();
6389 e.fillInStackTrace();
6390 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006391 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006392 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
6393 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
6394 }
6395 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006396 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
6397 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006398 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 + " during animation: policyVis=" + mPolicyVisibility
6400 + " attHidden=" + mAttachedHidden
6401 + " tok.hiddenRequested="
6402 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07006403 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006404 + (mAppToken != null ? mAppToken.hidden : false)
6405 + " animating=" + mAnimating
6406 + " tok animating="
6407 + (mAppToken != null ? mAppToken.animating : false));
6408 if (!showSurfaceRobustlyLocked(this)) {
6409 return false;
6410 }
6411 mLastAlpha = -1;
6412 mHasDrawn = true;
6413 mLastHidden = false;
6414 mReadyToShow = false;
6415 enableScreenIfNeededLocked();
6416
6417 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07006418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006419 int i = mChildWindows.size();
6420 while (i > 0) {
6421 i--;
6422 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07006423 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006424 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07006425 if (c.mSurface != null) {
6426 c.performShowLocked();
6427 // It hadn't been shown, which means layout not
6428 // performed on it, so now we want to make sure to
6429 // do a layout. If called from within the transaction
6430 // loop, this will cause it to restart with a new
6431 // layout.
6432 mLayoutNeeded = true;
6433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006434 }
6435 }
Romain Guy06882f82009-06-10 13:36:04 -07006436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 if (mAttrs.type != TYPE_APPLICATION_STARTING
6438 && mAppToken != null) {
6439 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006440
Dianne Hackborn248b1882009-09-16 16:46:44 -07006441 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006442 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07006443 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006444 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07006445 // If this initial window is animating, stop it -- we
6446 // will do an animation to reveal it from behind the
6447 // starting window, so there is no need for it to also
6448 // be doing its own stuff.
6449 if (mAnimation != null) {
6450 mAnimation = null;
6451 // Make sure we clean up the animation.
6452 mAnimating = true;
6453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 mFinishedStarting.add(mAppToken);
6455 mH.sendEmptyMessage(H.FINISHED_STARTING);
6456 }
6457 mAppToken.updateReportedVisibilityLocked();
6458 }
6459 }
6460 return true;
6461 }
Romain Guy06882f82009-06-10 13:36:04 -07006462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006463 // This must be called while inside a transaction. Returns true if
6464 // there is more animation to run.
6465 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08006466 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07006468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006469 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
6470 mHasTransformation = true;
6471 mHasLocalTransformation = true;
6472 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006473 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 TAG, "Starting animation in " + this +
6475 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
6476 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
6477 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
6478 mAnimation.setStartTime(currentTime);
6479 mLocalAnimating = true;
6480 mAnimating = true;
6481 }
6482 mTransformation.clear();
6483 final boolean more = mAnimation.getTransformation(
6484 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006485 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 TAG, "Stepped animation in " + this +
6487 ": more=" + more + ", xform=" + mTransformation);
6488 if (more) {
6489 // we're not done!
6490 return true;
6491 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006492 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006493 TAG, "Finished animation in " + this +
6494 " @ " + currentTime);
6495 mAnimation = null;
6496 //WindowManagerService.this.dump();
6497 }
6498 mHasLocalTransformation = false;
6499 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006500 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 // When our app token is animating, we kind-of pretend like
6502 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
6503 // part of this check means that we will only do this if
6504 // our window is not currently exiting, or it is not
6505 // locally animating itself. The idea being that one that
6506 // is exiting and doing a local animation should be removed
6507 // once that animation is done.
6508 mAnimating = true;
6509 mHasTransformation = true;
6510 mTransformation.clear();
6511 return false;
6512 } else if (mHasTransformation) {
6513 // Little trick to get through the path below to act like
6514 // we have finished an animation.
6515 mAnimating = true;
6516 } else if (isAnimating()) {
6517 mAnimating = true;
6518 }
6519 } else if (mAnimation != null) {
6520 // If the display is frozen, and there is a pending animation,
6521 // clear it and make sure we run the cleanup code.
6522 mAnimating = true;
6523 mLocalAnimating = true;
6524 mAnimation = null;
6525 }
Romain Guy06882f82009-06-10 13:36:04 -07006526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006527 if (!mAnimating && !mLocalAnimating) {
6528 return false;
6529 }
6530
Joe Onorato8a9b2202010-02-26 18:56:32 -08006531 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 TAG, "Animation done in " + this + ": exiting=" + mExiting
6533 + ", reportedVisible="
6534 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07006535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 mAnimating = false;
6537 mLocalAnimating = false;
6538 mAnimation = null;
6539 mAnimLayer = mLayer;
6540 if (mIsImWindow) {
6541 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006542 } else if (mIsWallpaper) {
6543 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006545 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006546 + " anim layer: " + mAnimLayer);
6547 mHasTransformation = false;
6548 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006549 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
6550 if (DEBUG_VISIBILITY) {
6551 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
6552 + mPolicyVisibilityAfterAnim);
6553 }
6554 mPolicyVisibility = mPolicyVisibilityAfterAnim;
6555 if (!mPolicyVisibility) {
6556 if (mCurrentFocus == this) {
6557 mFocusMayChange = true;
6558 }
6559 // Window is no longer visible -- make sure if we were waiting
6560 // for it to be displayed before enabling the display, that
6561 // we allow the display to be enabled now.
6562 enableScreenIfNeededLocked();
6563 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08006564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006565 mTransformation.clear();
6566 if (mHasDrawn
6567 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
6568 && mAppToken != null
6569 && mAppToken.firstWindowDrawn
6570 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006571 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006572 + mToken + ": first real window done animating");
6573 mFinishedStarting.add(mAppToken);
6574 mH.sendEmptyMessage(H.FINISHED_STARTING);
6575 }
Romain Guy06882f82009-06-10 13:36:04 -07006576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006577 finishExit();
6578
6579 if (mAppToken != null) {
6580 mAppToken.updateReportedVisibilityLocked();
6581 }
6582
6583 return false;
6584 }
6585
6586 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006587 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006588 TAG, "finishExit in " + this
6589 + ": exiting=" + mExiting
6590 + " remove=" + mRemoveOnExit
6591 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07006592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006593 final int N = mChildWindows.size();
6594 for (int i=0; i<N; i++) {
6595 ((WindowState)mChildWindows.get(i)).finishExit();
6596 }
Romain Guy06882f82009-06-10 13:36:04 -07006597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 if (!mExiting) {
6599 return;
6600 }
Romain Guy06882f82009-06-10 13:36:04 -07006601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 if (isWindowAnimating()) {
6603 return;
6604 }
6605
Joe Onorato8a9b2202010-02-26 18:56:32 -08006606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 TAG, "Exit animation finished in " + this
6608 + ": remove=" + mRemoveOnExit);
6609 if (mSurface != null) {
6610 mDestroySurface.add(this);
6611 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006612 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006613 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614 try {
6615 mSurface.hide();
6616 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006617 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 }
6619 mLastHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07006620
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006621 for (int i=0; i<N; i++) {
6622 mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i));
Jeff Brown349703e2010-06-22 01:27:15 -07006623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006624 }
6625 mExiting = false;
6626 if (mRemoveOnExit) {
6627 mPendingRemove.add(this);
6628 mRemoveOnExit = false;
6629 }
6630 }
Romain Guy06882f82009-06-10 13:36:04 -07006631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
6633 if (dsdx < .99999f || dsdx > 1.00001f) return false;
6634 if (dtdy < .99999f || dtdy > 1.00001f) return false;
6635 if (dtdx < -.000001f || dtdx > .000001f) return false;
6636 if (dsdy < -.000001f || dsdy > .000001f) return false;
6637 return true;
6638 }
Romain Guy06882f82009-06-10 13:36:04 -07006639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 void computeShownFrameLocked() {
6641 final boolean selfTransformation = mHasLocalTransformation;
6642 Transformation attachedTransformation =
6643 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
6644 ? mAttachedWindow.mTransformation : null;
6645 Transformation appTransformation =
6646 (mAppToken != null && mAppToken.hasTransformation)
6647 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006648
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006649 // Wallpapers are animated based on the "real" window they
6650 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006651 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07006652 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07006653 if (mWallpaperTarget.mHasLocalTransformation &&
6654 mWallpaperTarget.mAnimation != null &&
6655 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006656 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07006657 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006658 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07006659 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006660 }
6661 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07006662 mWallpaperTarget.mAppToken.hasTransformation &&
6663 mWallpaperTarget.mAppToken.animation != null &&
6664 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006665 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07006666 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006667 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07006668 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006669 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006670 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 if (selfTransformation || attachedTransformation != null
6673 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07006674 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 final Rect frame = mFrame;
6676 final float tmpFloats[] = mTmpFloats;
6677 final Matrix tmpMatrix = mTmpMatrix;
6678
6679 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07006680 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07006682 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07006684 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07006686 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687 }
6688 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07006689 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 }
6691
6692 // "convert" it into SurfaceFlinger's format
6693 // (a 2x2 matrix + an offset)
6694 // Here we must not transform the position of the surface
6695 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006696 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07006697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 tmpMatrix.getValues(tmpFloats);
6699 mDsDx = tmpFloats[Matrix.MSCALE_X];
6700 mDtDx = tmpFloats[Matrix.MSKEW_X];
6701 mDsDy = tmpFloats[Matrix.MSKEW_Y];
6702 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006703 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
6704 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006705 int w = frame.width();
6706 int h = frame.height();
6707 mShownFrame.set(x, y, x+w, y+h);
6708
6709 // Now set the alpha... but because our current hardware
6710 // can't do alpha transformation on a non-opaque surface,
6711 // turn it off if we are running an animation that is also
6712 // transforming since it is more important to have that
6713 // animation be smooth.
6714 mShownAlpha = mAlpha;
6715 if (!mLimitedAlphaCompositing
6716 || (!PixelFormat.formatHasAlpha(mAttrs.format)
6717 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
6718 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006719 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 if (selfTransformation) {
6721 mShownAlpha *= mTransformation.getAlpha();
6722 }
6723 if (attachedTransformation != null) {
6724 mShownAlpha *= attachedTransformation.getAlpha();
6725 }
6726 if (appTransformation != null) {
6727 mShownAlpha *= appTransformation.getAlpha();
6728 }
6729 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006730 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 }
Romain Guy06882f82009-06-10 13:36:04 -07006732
Joe Onorato8a9b2202010-02-26 18:56:32 -08006733 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006734 TAG, "Continuing animation in " + this +
6735 ": " + mShownFrame +
6736 ", alpha=" + mTransformation.getAlpha());
6737 return;
6738 }
Romain Guy06882f82009-06-10 13:36:04 -07006739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006741 if (mXOffset != 0 || mYOffset != 0) {
6742 mShownFrame.offset(mXOffset, mYOffset);
6743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 mShownAlpha = mAlpha;
6745 mDsDx = 1;
6746 mDtDx = 0;
6747 mDsDy = 0;
6748 mDtDy = 1;
6749 }
Romain Guy06882f82009-06-10 13:36:04 -07006750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006751 /**
6752 * Is this window visible? It is not visible if there is no
6753 * surface, or we are in the process of running an exit animation
6754 * that will remove the surface, or its app token has been hidden.
6755 */
6756 public boolean isVisibleLw() {
6757 final AppWindowToken atoken = mAppToken;
6758 return mSurface != null && mPolicyVisibility && !mAttachedHidden
6759 && (atoken == null || !atoken.hiddenRequested)
6760 && !mExiting && !mDestroying;
6761 }
6762
6763 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07006764 * Like {@link #isVisibleLw}, but also counts a window that is currently
6765 * "hidden" behind the keyguard as visible. This allows us to apply
6766 * things like window flags that impact the keyguard.
6767 * XXX I am starting to think we need to have ANOTHER visibility flag
6768 * for this "hidden behind keyguard" state rather than overloading
6769 * mPolicyVisibility. Ungh.
6770 */
6771 public boolean isVisibleOrBehindKeyguardLw() {
6772 final AppWindowToken atoken = mAppToken;
6773 return mSurface != null && !mAttachedHidden
6774 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackborn5943c202010-04-12 21:36:49 -07006775 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending))
Dianne Hackborn3d163f072009-10-07 21:26:57 -07006776 && !mExiting && !mDestroying;
6777 }
6778
6779 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 * Is this window visible, ignoring its app token? It is not visible
6781 * if there is no surface, or we are in the process of running an exit animation
6782 * that will remove the surface.
6783 */
6784 public boolean isWinVisibleLw() {
6785 final AppWindowToken atoken = mAppToken;
6786 return mSurface != null && mPolicyVisibility && !mAttachedHidden
6787 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
6788 && !mExiting && !mDestroying;
6789 }
6790
6791 /**
6792 * The same as isVisible(), but follows the current hidden state of
6793 * the associated app token, not the pending requested hidden state.
6794 */
6795 boolean isVisibleNow() {
6796 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07006797 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 }
6799
6800 /**
6801 * Same as isVisible(), but we also count it as visible between the
6802 * call to IWindowSession.add() and the first relayout().
6803 */
6804 boolean isVisibleOrAdding() {
6805 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006806 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006807 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
6808 && mPolicyVisibility && !mAttachedHidden
6809 && (atoken == null || !atoken.hiddenRequested)
6810 && !mExiting && !mDestroying;
6811 }
6812
6813 /**
6814 * Is this window currently on-screen? It is on-screen either if it
6815 * is visible or it is currently running an animation before no longer
6816 * being visible.
6817 */
6818 boolean isOnScreen() {
6819 final AppWindowToken atoken = mAppToken;
6820 if (atoken != null) {
6821 return mSurface != null && mPolicyVisibility && !mDestroying
6822 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07006823 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 } else {
6825 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07006826 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006827 }
6828 }
Romain Guy06882f82009-06-10 13:36:04 -07006829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006830 /**
6831 * Like isOnScreen(), but we don't return true if the window is part
6832 * of a transition that has not yet been started.
6833 */
6834 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07006835 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07006836 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07006837 return false;
6838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07006840 final boolean animating = atoken != null
6841 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006843 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
6844 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07006845 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 }
6847
6848 /** Is the window or its container currently animating? */
6849 boolean isAnimating() {
6850 final WindowState attached = mAttachedWindow;
6851 final AppWindowToken atoken = mAppToken;
6852 return mAnimation != null
6853 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07006854 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 (atoken.animation != null
6856 || atoken.inPendingTransaction));
6857 }
6858
6859 /** Is this window currently animating? */
6860 boolean isWindowAnimating() {
6861 return mAnimation != null;
6862 }
6863
6864 /**
6865 * Like isOnScreen, but returns false if the surface hasn't yet
6866 * been drawn.
6867 */
6868 public boolean isDisplayedLw() {
6869 final AppWindowToken atoken = mAppToken;
6870 return mSurface != null && mPolicyVisibility && !mDestroying
6871 && !mDrawPending && !mCommitDrawPending
6872 && ((!mAttachedHidden &&
6873 (atoken == null || !atoken.hiddenRequested))
6874 || mAnimating);
6875 }
6876
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006877 /**
6878 * Returns true if the window has a surface that it has drawn a
Dianne Hackborn5943c202010-04-12 21:36:49 -07006879 * complete UI in to. Note that this returns true if the orientation
6880 * is changing even if the window hasn't redrawn because we don't want
6881 * to stop things from executing during that time.
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006882 */
6883 public boolean isDrawnLw() {
6884 final AppWindowToken atoken = mAppToken;
6885 return mSurface != null && !mDestroying
Dianne Hackborn5943c202010-04-12 21:36:49 -07006886 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending));
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006887 }
6888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 public boolean fillsScreenLw(int screenWidth, int screenHeight,
6890 boolean shownFrame, boolean onlyOpaque) {
6891 if (mSurface == null) {
6892 return false;
6893 }
6894 if (mAppToken != null && !mAppToken.appFullscreen) {
6895 return false;
6896 }
6897 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
6898 return false;
6899 }
6900 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006901
6902 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
6903 return frame.left <= mCompatibleScreenFrame.left &&
6904 frame.top <= mCompatibleScreenFrame.top &&
6905 frame.right >= mCompatibleScreenFrame.right &&
6906 frame.bottom >= mCompatibleScreenFrame.bottom;
6907 } else {
6908 return frame.left <= 0 && frame.top <= 0
6909 && frame.right >= screenWidth
6910 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 }
Romain Guy06882f82009-06-10 13:36:04 -07006913
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006914 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07006915 * Return true if the window is opaque and fully drawn. This indicates
6916 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006917 */
6918 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07006919 return (mAttrs.format == PixelFormat.OPAQUE
6920 || mAttrs.type == TYPE_WALLPAPER)
6921 && mSurface != null && mAnimation == null
6922 && (mAppToken == null || mAppToken.animation == null)
6923 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006924 }
6925
6926 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
6927 return
6928 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006929 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
6930 // only if it's visible
6931 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006932 // and only if the application fills the compatible screen
6933 mFrame.left <= mCompatibleScreenFrame.left &&
6934 mFrame.top <= mCompatibleScreenFrame.top &&
6935 mFrame.right >= mCompatibleScreenFrame.right &&
6936 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006937 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006938 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006939 }
6940
6941 boolean isFullscreen(int screenWidth, int screenHeight) {
6942 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006943 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 }
6945
6946 void removeLocked() {
6947 if (mAttachedWindow != null) {
6948 mAttachedWindow.mChildWindows.remove(this);
6949 }
6950 destroySurfaceLocked();
6951 mSession.windowRemovedLocked();
6952 try {
6953 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
6954 } catch (RuntimeException e) {
6955 // Ignore if it has already been removed (usually because
6956 // we are doing this as part of processing a death note.)
6957 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006958
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006959 if (mInputChannel != null) {
6960 mInputManager.unregisterInputChannel(mInputChannel);
6961
6962 mInputChannel.dispose();
6963 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 }
6966
6967 private class DeathRecipient implements IBinder.DeathRecipient {
6968 public void binderDied() {
6969 try {
6970 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006971 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006972 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 if (win != null) {
6974 removeWindowLocked(mSession, win);
6975 }
6976 }
6977 } catch (IllegalArgumentException ex) {
6978 // This will happen if the window has already been
6979 // removed.
6980 }
6981 }
6982 }
6983
6984 /** Returns true if this window desires key events. */
6985 public final boolean canReceiveKeys() {
6986 return isVisibleOrAdding()
6987 && (mViewVisibility == View.VISIBLE)
6988 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
6989 }
6990
6991 public boolean hasDrawnLw() {
6992 return mHasDrawn;
6993 }
6994
6995 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006996 return showLw(doAnimation, true);
6997 }
6998
6999 boolean showLw(boolean doAnimation, boolean requestAnim) {
7000 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7001 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007003 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007004 if (doAnimation) {
7005 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7006 + mPolicyVisibility + " mAnimation=" + mAnimation);
7007 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7008 doAnimation = false;
7009 } else if (mPolicyVisibility && mAnimation == null) {
7010 // Check for the case where we are currently visible and
7011 // not animating; we do not want to do animation at such a
7012 // point to become visible when we already are.
7013 doAnimation = false;
7014 }
7015 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007016 mPolicyVisibility = true;
7017 mPolicyVisibilityAfterAnim = true;
7018 if (doAnimation) {
7019 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7020 }
7021 if (requestAnim) {
7022 requestAnimationLocked(0);
7023 }
7024 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 }
7026
7027 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007028 return hideLw(doAnimation, true);
7029 }
7030
7031 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007032 if (doAnimation) {
7033 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7034 doAnimation = false;
7035 }
7036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7038 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007039 if (!current) {
7040 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007042 if (doAnimation) {
7043 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7044 if (mAnimation == null) {
7045 doAnimation = false;
7046 }
7047 }
7048 if (doAnimation) {
7049 mPolicyVisibilityAfterAnim = false;
7050 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007051 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007052 mPolicyVisibilityAfterAnim = false;
7053 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007054 // Window is no longer visible -- make sure if we were waiting
7055 // for it to be displayed before enabling the display, that
7056 // we allow the display to be enabled now.
7057 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007058 if (mCurrentFocus == this) {
7059 mFocusMayChange = true;
7060 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007061 }
7062 if (requestAnim) {
7063 requestAnimationLocked(0);
7064 }
7065 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007066 }
7067
7068 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007069 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7070 pw.print(" mClient="); pw.println(mClient.asBinder());
7071 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7072 if (mAttachedWindow != null || mLayoutAttached) {
7073 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7074 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7075 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007076 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7077 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7078 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007079 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7080 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007081 }
7082 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7083 pw.print(" mSubLayer="); pw.print(mSubLayer);
7084 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7085 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7086 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7087 pw.print("="); pw.print(mAnimLayer);
7088 pw.print(" mLastLayer="); pw.println(mLastLayer);
7089 if (mSurface != null) {
7090 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007091 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7092 pw.print(" layer="); pw.print(mSurfaceLayer);
7093 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7094 pw.print(" rect=("); pw.print(mSurfaceX);
7095 pw.print(","); pw.print(mSurfaceY);
7096 pw.print(") "); pw.print(mSurfaceW);
7097 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007098 }
7099 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7100 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7101 if (mAppToken != null) {
7102 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7103 }
7104 if (mTargetAppToken != null) {
7105 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7106 }
7107 pw.print(prefix); pw.print("mViewVisibility=0x");
7108 pw.print(Integer.toHexString(mViewVisibility));
7109 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007110 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7111 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007112 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7113 pw.print(prefix); pw.print("mPolicyVisibility=");
7114 pw.print(mPolicyVisibility);
7115 pw.print(" mPolicyVisibilityAfterAnim=");
7116 pw.print(mPolicyVisibilityAfterAnim);
7117 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7118 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007119 if (!mRelayoutCalled) {
7120 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7121 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007122 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007123 pw.print(" h="); pw.print(mRequestedHeight);
7124 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007125 if (mXOffset != 0 || mYOffset != 0) {
7126 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7127 pw.print(" y="); pw.println(mYOffset);
7128 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007129 pw.print(prefix); pw.print("mGivenContentInsets=");
7130 mGivenContentInsets.printShortString(pw);
7131 pw.print(" mGivenVisibleInsets=");
7132 mGivenVisibleInsets.printShortString(pw);
7133 pw.println();
7134 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7135 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7136 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7137 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007138 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007139 pw.print(prefix); pw.print("mShownFrame=");
7140 mShownFrame.printShortString(pw);
7141 pw.print(" last="); mLastShownFrame.printShortString(pw);
7142 pw.println();
7143 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7144 pw.print(" last="); mLastFrame.printShortString(pw);
7145 pw.println();
7146 pw.print(prefix); pw.print("mContainingFrame=");
7147 mContainingFrame.printShortString(pw);
7148 pw.print(" mDisplayFrame=");
7149 mDisplayFrame.printShortString(pw);
7150 pw.println();
7151 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7152 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7153 pw.println();
7154 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7155 pw.print(" last="); mLastContentInsets.printShortString(pw);
7156 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7157 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7158 pw.println();
7159 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7160 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7161 pw.print(" mAlpha="); pw.print(mAlpha);
7162 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7163 }
7164 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7165 || mAnimation != null) {
7166 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7167 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7168 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7169 pw.print(" mAnimation="); pw.println(mAnimation);
7170 }
7171 if (mHasTransformation || mHasLocalTransformation) {
7172 pw.print(prefix); pw.print("XForm: has=");
7173 pw.print(mHasTransformation);
7174 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7175 pw.print(" "); mTransformation.printShortString(pw);
7176 pw.println();
7177 }
7178 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7179 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7180 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7181 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7182 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7183 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7184 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7185 pw.print(" mDestroying="); pw.print(mDestroying);
7186 pw.print(" mRemoved="); pw.println(mRemoved);
7187 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007188 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007189 pw.print(prefix); pw.print("mOrientationChanging=");
7190 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007191 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7192 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007193 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007194 if (mHScale != 1 || mVScale != 1) {
7195 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7196 pw.print(" mVScale="); pw.println(mVScale);
7197 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007198 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007199 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7200 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7201 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007202 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7203 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7204 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007207
7208 String makeInputChannelName() {
7209 return Integer.toHexString(System.identityHashCode(this))
7210 + " " + mAttrs.getTitle();
7211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212
7213 @Override
7214 public String toString() {
7215 return "Window{"
7216 + Integer.toHexString(System.identityHashCode(this))
7217 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7218 }
7219 }
Romain Guy06882f82009-06-10 13:36:04 -07007220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007221 // -------------------------------------------------------------
7222 // Window Token State
7223 // -------------------------------------------------------------
7224
7225 class WindowToken {
7226 // The actual token.
7227 final IBinder token;
7228
7229 // The type of window this token is for, as per WindowManager.LayoutParams.
7230 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07007231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007232 // Set if this token was explicitly added by a client, so should
7233 // not be removed when all windows are removed.
7234 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07007235
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007236 // For printing.
7237 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07007238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007239 // If this is an AppWindowToken, this is non-null.
7240 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07007241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007242 // All of the windows associated with this token.
7243 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
7244
7245 // Is key dispatching paused for this token?
7246 boolean paused = false;
7247
7248 // Should this token's windows be hidden?
7249 boolean hidden;
7250
7251 // Temporary for finding which tokens no longer have visible windows.
7252 boolean hasVisible;
7253
Dianne Hackborna8f60182009-09-01 19:01:50 -07007254 // Set to true when this token is in a pending transaction where it
7255 // will be shown.
7256 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007257
Dianne Hackborna8f60182009-09-01 19:01:50 -07007258 // Set to true when this token is in a pending transaction where it
7259 // will be hidden.
7260 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007261
Dianne Hackborna8f60182009-09-01 19:01:50 -07007262 // Set to true when this token is in a pending transaction where its
7263 // windows will be put to the bottom of the list.
7264 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007265
Dianne Hackborna8f60182009-09-01 19:01:50 -07007266 // Set to true when this token is in a pending transaction where its
7267 // windows will be put to the top of the list.
7268 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 WindowToken(IBinder _token, int type, boolean _explicit) {
7271 token = _token;
7272 windowType = type;
7273 explicit = _explicit;
7274 }
7275
7276 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007277 pw.print(prefix); pw.print("token="); pw.println(token);
7278 pw.print(prefix); pw.print("windows="); pw.println(windows);
7279 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
7280 pw.print(" hidden="); pw.print(hidden);
7281 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007282 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
7283 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
7284 pw.print(" waitingToHide="); pw.print(waitingToHide);
7285 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
7286 pw.print(" sendingToTop="); pw.println(sendingToTop);
7287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 }
7289
7290 @Override
7291 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007292 if (stringName == null) {
7293 StringBuilder sb = new StringBuilder();
7294 sb.append("WindowToken{");
7295 sb.append(Integer.toHexString(System.identityHashCode(this)));
7296 sb.append(" token="); sb.append(token); sb.append('}');
7297 stringName = sb.toString();
7298 }
7299 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007300 }
7301 };
7302
7303 class AppWindowToken extends WindowToken {
7304 // Non-null only for application tokens.
7305 final IApplicationToken appToken;
7306
7307 // All of the windows and child windows that are included in this
7308 // application token. Note this list is NOT sorted!
7309 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
7310
7311 int groupId = -1;
7312 boolean appFullscreen;
7313 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07007314
7315 // The input dispatching timeout for this application token in nanoseconds.
7316 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07007317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007318 // These are used for determining when all windows associated with
7319 // an activity have been drawn, so they can be made visible together
7320 // at the same time.
7321 int lastTransactionSequence = mTransactionSequence-1;
7322 int numInterestingWindows;
7323 int numDrawnWindows;
7324 boolean inPendingTransaction;
7325 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07007326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 // Is this token going to be hidden in a little while? If so, it
7328 // won't be taken into account for setting the screen orientation.
7329 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007331 // Is this window's surface needed? This is almost like hidden, except
7332 // it will sometimes be true a little earlier: when the token has
7333 // been shown, but is still waiting for its app transition to execute
7334 // before making its windows shown.
7335 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07007336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 // Have we told the window clients to hide themselves?
7338 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 // Last visibility state we reported to the app token.
7341 boolean reportedVisible;
7342
7343 // Set to true when the token has been removed from the window mgr.
7344 boolean removed;
7345
7346 // Have we been asked to have this token keep the screen frozen?
7347 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07007348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007349 boolean animating;
7350 Animation animation;
7351 boolean hasTransformation;
7352 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07007353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007354 // Offset to the window of all layers in the token, for use by
7355 // AppWindowToken animations.
7356 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07007357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 // Information about an application starting window if displayed.
7359 StartingData startingData;
7360 WindowState startingWindow;
7361 View startingView;
7362 boolean startingDisplayed;
7363 boolean startingMoved;
7364 boolean firstWindowDrawn;
7365
7366 AppWindowToken(IApplicationToken _token) {
7367 super(_token.asBinder(),
7368 WindowManager.LayoutParams.TYPE_APPLICATION, true);
7369 appWindowToken = this;
7370 appToken = _token;
7371 }
Romain Guy06882f82009-06-10 13:36:04 -07007372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007373 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007374 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 TAG, "Setting animation in " + this + ": " + anim);
7376 animation = anim;
7377 animating = false;
7378 anim.restrictDuration(MAX_ANIMATION_DURATION);
7379 anim.scaleCurrentDuration(mTransitionAnimationScale);
7380 int zorder = anim.getZAdjustment();
7381 int adj = 0;
7382 if (zorder == Animation.ZORDER_TOP) {
7383 adj = TYPE_LAYER_OFFSET;
7384 } else if (zorder == Animation.ZORDER_BOTTOM) {
7385 adj = -TYPE_LAYER_OFFSET;
7386 }
Romain Guy06882f82009-06-10 13:36:04 -07007387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007388 if (animLayerAdjustment != adj) {
7389 animLayerAdjustment = adj;
7390 updateLayers();
7391 }
7392 }
Romain Guy06882f82009-06-10 13:36:04 -07007393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 public void setDummyAnimation() {
7395 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007396 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007397 TAG, "Setting dummy animation in " + this);
7398 animation = sDummyAnimation;
7399 }
7400 }
7401
7402 public void clearAnimation() {
7403 if (animation != null) {
7404 animation = null;
7405 animating = true;
7406 }
7407 }
Romain Guy06882f82009-06-10 13:36:04 -07007408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 void updateLayers() {
7410 final int N = allAppWindows.size();
7411 final int adj = animLayerAdjustment;
7412 for (int i=0; i<N; i++) {
7413 WindowState w = allAppWindows.get(i);
7414 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007415 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007416 + w.mAnimLayer);
7417 if (w == mInputMethodTarget) {
7418 setInputMethodAnimLayerAdjustment(adj);
7419 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007420 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007421 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007423 }
7424 }
Romain Guy06882f82009-06-10 13:36:04 -07007425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 void sendAppVisibilityToClients() {
7427 final int N = allAppWindows.size();
7428 for (int i=0; i<N; i++) {
7429 WindowState win = allAppWindows.get(i);
7430 if (win == startingWindow && clientHidden) {
7431 // Don't hide the starting window.
7432 continue;
7433 }
7434 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007435 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007436 "Setting visibility of " + win + ": " + (!clientHidden));
7437 win.mClient.dispatchAppVisibility(!clientHidden);
7438 } catch (RemoteException e) {
7439 }
7440 }
7441 }
Romain Guy06882f82009-06-10 13:36:04 -07007442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007443 void showAllWindowsLocked() {
7444 final int NW = allAppWindows.size();
7445 for (int i=0; i<NW; i++) {
7446 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007447 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 "performing show on: " + w);
7449 w.performShowLocked();
7450 }
7451 }
Romain Guy06882f82009-06-10 13:36:04 -07007452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 // This must be called while inside a transaction.
7454 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007455 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007458 if (animation == sDummyAnimation) {
7459 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007460 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007461 // when it is really time to animate, this will be set to
7462 // a real animation and the next call will execute normally.
7463 return false;
7464 }
Romain Guy06882f82009-06-10 13:36:04 -07007465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 if ((allDrawn || animating || startingDisplayed) && animation != null) {
7467 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007468 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007469 TAG, "Starting animation in " + this +
7470 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
7471 + " scale=" + mTransitionAnimationScale
7472 + " allDrawn=" + allDrawn + " animating=" + animating);
7473 animation.initialize(dw, dh, dw, dh);
7474 animation.setStartTime(currentTime);
7475 animating = true;
7476 }
7477 transformation.clear();
7478 final boolean more = animation.getTransformation(
7479 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007480 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 TAG, "Stepped animation in " + this +
7482 ": more=" + more + ", xform=" + transformation);
7483 if (more) {
7484 // we're done!
7485 hasTransformation = true;
7486 return true;
7487 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007488 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007489 TAG, "Finished animation in " + this +
7490 " @ " + currentTime);
7491 animation = null;
7492 }
7493 } else if (animation != null) {
7494 // If the display is frozen, and there is a pending animation,
7495 // clear it and make sure we run the cleanup code.
7496 animating = true;
7497 animation = null;
7498 }
7499
7500 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07007501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 if (!animating) {
7503 return false;
7504 }
7505
7506 clearAnimation();
7507 animating = false;
7508 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
7509 moveInputMethodWindowsIfNeededLocked(true);
7510 }
Romain Guy06882f82009-06-10 13:36:04 -07007511
Joe Onorato8a9b2202010-02-26 18:56:32 -08007512 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 TAG, "Animation done in " + this
7514 + ": reportedVisible=" + reportedVisible);
7515
7516 transformation.clear();
7517 if (animLayerAdjustment != 0) {
7518 animLayerAdjustment = 0;
7519 updateLayers();
7520 }
Romain Guy06882f82009-06-10 13:36:04 -07007521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007522 final int N = windows.size();
7523 for (int i=0; i<N; i++) {
7524 ((WindowState)windows.get(i)).finishExit();
7525 }
7526 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07007527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 return false;
7529 }
7530
7531 void updateReportedVisibilityLocked() {
7532 if (appToken == null) {
7533 return;
7534 }
Romain Guy06882f82009-06-10 13:36:04 -07007535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 int numInteresting = 0;
7537 int numVisible = 0;
7538 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07007539
Joe Onorato8a9b2202010-02-26 18:56:32 -08007540 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 final int N = allAppWindows.size();
7542 for (int i=0; i<N; i++) {
7543 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08007544 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07007545 || win.mViewVisibility != View.VISIBLE
7546 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007547 continue;
7548 }
7549 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007550 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007551 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007552 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007553 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007554 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 + " pv=" + win.mPolicyVisibility
7556 + " dp=" + win.mDrawPending
7557 + " cdp=" + win.mCommitDrawPending
7558 + " ah=" + win.mAttachedHidden
7559 + " th="
7560 + (win.mAppToken != null
7561 ? win.mAppToken.hiddenRequested : false)
7562 + " a=" + win.mAnimating);
7563 }
7564 }
7565 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007566 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 if (!win.isAnimating()) {
7568 numVisible++;
7569 }
7570 nowGone = false;
7571 } else if (win.isAnimating()) {
7572 nowGone = false;
7573 }
7574 }
Romain Guy06882f82009-06-10 13:36:04 -07007575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007576 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007577 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007578 + numInteresting + " visible=" + numVisible);
7579 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007580 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007581 TAG, "Visibility changed in " + this
7582 + ": vis=" + nowVisible);
7583 reportedVisible = nowVisible;
7584 Message m = mH.obtainMessage(
7585 H.REPORT_APPLICATION_TOKEN_WINDOWS,
7586 nowVisible ? 1 : 0,
7587 nowGone ? 1 : 0,
7588 this);
7589 mH.sendMessage(m);
7590 }
7591 }
Romain Guy06882f82009-06-10 13:36:04 -07007592
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007593 WindowState findMainWindow() {
7594 int j = windows.size();
7595 while (j > 0) {
7596 j--;
7597 WindowState win = windows.get(j);
7598 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
7599 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
7600 return win;
7601 }
7602 }
7603 return null;
7604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007606 void dump(PrintWriter pw, String prefix) {
7607 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007608 if (appToken != null) {
7609 pw.print(prefix); pw.println("app=true");
7610 }
7611 if (allAppWindows.size() > 0) {
7612 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
7613 }
7614 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007615 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007616 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
7617 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
7618 pw.print(" clientHidden="); pw.print(clientHidden);
7619 pw.print(" willBeHidden="); pw.print(willBeHidden);
7620 pw.print(" reportedVisible="); pw.println(reportedVisible);
7621 if (paused || freezingScreen) {
7622 pw.print(prefix); pw.print("paused="); pw.print(paused);
7623 pw.print(" freezingScreen="); pw.println(freezingScreen);
7624 }
7625 if (numInterestingWindows != 0 || numDrawnWindows != 0
7626 || inPendingTransaction || allDrawn) {
7627 pw.print(prefix); pw.print("numInterestingWindows=");
7628 pw.print(numInterestingWindows);
7629 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
7630 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
7631 pw.print(" allDrawn="); pw.println(allDrawn);
7632 }
7633 if (animating || animation != null) {
7634 pw.print(prefix); pw.print("animating="); pw.print(animating);
7635 pw.print(" animation="); pw.println(animation);
7636 }
7637 if (animLayerAdjustment != 0) {
7638 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
7639 }
7640 if (hasTransformation) {
7641 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
7642 pw.print(" transformation="); transformation.printShortString(pw);
7643 pw.println();
7644 }
7645 if (startingData != null || removed || firstWindowDrawn) {
7646 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
7647 pw.print(" removed="); pw.print(removed);
7648 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
7649 }
7650 if (startingWindow != null || startingView != null
7651 || startingDisplayed || startingMoved) {
7652 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
7653 pw.print(" startingView="); pw.print(startingView);
7654 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
7655 pw.print(" startingMoved"); pw.println(startingMoved);
7656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 }
7658
7659 @Override
7660 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007661 if (stringName == null) {
7662 StringBuilder sb = new StringBuilder();
7663 sb.append("AppWindowToken{");
7664 sb.append(Integer.toHexString(System.identityHashCode(this)));
7665 sb.append(" token="); sb.append(token); sb.append('}');
7666 stringName = sb.toString();
7667 }
7668 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 }
7670 }
Romain Guy06882f82009-06-10 13:36:04 -07007671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 // -------------------------------------------------------------
7673 // DummyAnimation
7674 // -------------------------------------------------------------
7675
7676 // This is an animation that does nothing: it just immediately finishes
7677 // itself every time it is called. It is used as a stub animation in cases
7678 // where we want to synchronize multiple things that may be animating.
7679 static final class DummyAnimation extends Animation {
7680 public boolean getTransformation(long currentTime, Transformation outTransformation) {
7681 return false;
7682 }
7683 }
7684 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07007685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 // -------------------------------------------------------------
7687 // Async Handler
7688 // -------------------------------------------------------------
7689
7690 static final class StartingData {
7691 final String pkg;
7692 final int theme;
7693 final CharSequence nonLocalizedLabel;
7694 final int labelRes;
7695 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07007696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007697 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
7698 int _labelRes, int _icon) {
7699 pkg = _pkg;
7700 theme = _theme;
7701 nonLocalizedLabel = _nonLocalizedLabel;
7702 labelRes = _labelRes;
7703 icon = _icon;
7704 }
7705 }
7706
7707 private final class H extends Handler {
7708 public static final int REPORT_FOCUS_CHANGE = 2;
7709 public static final int REPORT_LOSING_FOCUS = 3;
7710 public static final int ANIMATE = 4;
7711 public static final int ADD_STARTING = 5;
7712 public static final int REMOVE_STARTING = 6;
7713 public static final int FINISHED_STARTING = 7;
7714 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007715 public static final int WINDOW_FREEZE_TIMEOUT = 11;
7716 public static final int HOLD_SCREEN_CHANGED = 12;
7717 public static final int APP_TRANSITION_TIMEOUT = 13;
7718 public static final int PERSIST_ANIMATION_SCALE = 14;
7719 public static final int FORCE_GC = 15;
7720 public static final int ENABLE_SCREEN = 16;
7721 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007722 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007723 public static final int WINDOWS_CHANGED = 19;
Romain Guy06882f82009-06-10 13:36:04 -07007724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07007726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007727 public H() {
7728 }
Romain Guy06882f82009-06-10 13:36:04 -07007729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007730 @Override
7731 public void handleMessage(Message msg) {
7732 switch (msg.what) {
7733 case REPORT_FOCUS_CHANGE: {
7734 WindowState lastFocus;
7735 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007737 synchronized(mWindowMap) {
7738 lastFocus = mLastFocus;
7739 newFocus = mCurrentFocus;
7740 if (lastFocus == newFocus) {
7741 // Focus is not changing, so nothing to do.
7742 return;
7743 }
7744 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007745 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007746 // + " to " + newFocus);
7747 if (newFocus != null && lastFocus != null
7748 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007749 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007750 mLosingFocus.add(lastFocus);
7751 lastFocus = null;
7752 }
7753 }
7754
7755 if (lastFocus != newFocus) {
7756 //System.out.println("Changing focus from " + lastFocus
7757 // + " to " + newFocus);
7758 if (newFocus != null) {
7759 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007760 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
7762 } catch (RemoteException e) {
7763 // Ignore if process has died.
7764 }
7765 }
7766
7767 if (lastFocus != null) {
7768 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007769 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
7771 } catch (RemoteException e) {
7772 // Ignore if process has died.
7773 }
7774 }
7775 }
7776 } break;
7777
7778 case REPORT_LOSING_FOCUS: {
7779 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007781 synchronized(mWindowMap) {
7782 losers = mLosingFocus;
7783 mLosingFocus = new ArrayList<WindowState>();
7784 }
7785
7786 final int N = losers.size();
7787 for (int i=0; i<N; i++) {
7788 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007789 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
7791 } catch (RemoteException e) {
7792 // Ignore if process has died.
7793 }
7794 }
7795 } break;
7796
7797 case ANIMATE: {
7798 synchronized(mWindowMap) {
7799 mAnimationPending = false;
7800 performLayoutAndPlaceSurfacesLocked();
7801 }
7802 } break;
7803
7804 case ADD_STARTING: {
7805 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7806 final StartingData sd = wtoken.startingData;
7807
7808 if (sd == null) {
7809 // Animation has been canceled... do nothing.
7810 return;
7811 }
Romain Guy06882f82009-06-10 13:36:04 -07007812
Joe Onorato8a9b2202010-02-26 18:56:32 -08007813 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007816 View view = null;
7817 try {
7818 view = mPolicy.addStartingWindow(
7819 wtoken.token, sd.pkg,
7820 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
7821 sd.icon);
7822 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007823 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007824 }
7825
7826 if (view != null) {
7827 boolean abort = false;
7828
7829 synchronized(mWindowMap) {
7830 if (wtoken.removed || wtoken.startingData == null) {
7831 // If the window was successfully added, then
7832 // we need to remove it.
7833 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007834 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 "Aborted starting " + wtoken
7836 + ": removed=" + wtoken.removed
7837 + " startingData=" + wtoken.startingData);
7838 wtoken.startingWindow = null;
7839 wtoken.startingData = null;
7840 abort = true;
7841 }
7842 } else {
7843 wtoken.startingView = view;
7844 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007845 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 "Added starting " + wtoken
7847 + ": startingWindow="
7848 + wtoken.startingWindow + " startingView="
7849 + wtoken.startingView);
7850 }
7851
7852 if (abort) {
7853 try {
7854 mPolicy.removeStartingWindow(wtoken.token, view);
7855 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007856 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 }
7858 }
7859 }
7860 } break;
7861
7862 case REMOVE_STARTING: {
7863 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7864 IBinder token = null;
7865 View view = null;
7866 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007867 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007868 + wtoken + ": startingWindow="
7869 + wtoken.startingWindow + " startingView="
7870 + wtoken.startingView);
7871 if (wtoken.startingWindow != null) {
7872 view = wtoken.startingView;
7873 token = wtoken.token;
7874 wtoken.startingData = null;
7875 wtoken.startingView = null;
7876 wtoken.startingWindow = null;
7877 }
7878 }
7879 if (view != null) {
7880 try {
7881 mPolicy.removeStartingWindow(token, view);
7882 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007883 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007884 }
7885 }
7886 } break;
7887
7888 case FINISHED_STARTING: {
7889 IBinder token = null;
7890 View view = null;
7891 while (true) {
7892 synchronized (mWindowMap) {
7893 final int N = mFinishedStarting.size();
7894 if (N <= 0) {
7895 break;
7896 }
7897 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7898
Joe Onorato8a9b2202010-02-26 18:56:32 -08007899 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007900 "Finished starting " + wtoken
7901 + ": startingWindow=" + wtoken.startingWindow
7902 + " startingView=" + wtoken.startingView);
7903
7904 if (wtoken.startingWindow == null) {
7905 continue;
7906 }
7907
7908 view = wtoken.startingView;
7909 token = wtoken.token;
7910 wtoken.startingData = null;
7911 wtoken.startingView = null;
7912 wtoken.startingWindow = null;
7913 }
7914
7915 try {
7916 mPolicy.removeStartingWindow(token, view);
7917 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007918 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 }
7920 }
7921 } break;
7922
7923 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7924 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7925
7926 boolean nowVisible = msg.arg1 != 0;
7927 boolean nowGone = msg.arg2 != 0;
7928
7929 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007930 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931 TAG, "Reporting visible in " + wtoken
7932 + " visible=" + nowVisible
7933 + " gone=" + nowGone);
7934 if (nowVisible) {
7935 wtoken.appToken.windowsVisible();
7936 } else {
7937 wtoken.appToken.windowsGone();
7938 }
7939 } catch (RemoteException ex) {
7940 }
7941 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 case WINDOW_FREEZE_TIMEOUT: {
7944 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007945 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 int i = mWindows.size();
7947 while (i > 0) {
7948 i--;
7949 WindowState w = (WindowState)mWindows.get(i);
7950 if (w.mOrientationChanging) {
7951 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007952 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 }
7954 }
7955 performLayoutAndPlaceSurfacesLocked();
7956 }
7957 break;
7958 }
Romain Guy06882f82009-06-10 13:36:04 -07007959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007960 case HOLD_SCREEN_CHANGED: {
7961 Session oldHold;
7962 Session newHold;
7963 synchronized (mWindowMap) {
7964 oldHold = mLastReportedHold;
7965 newHold = (Session)msg.obj;
7966 mLastReportedHold = newHold;
7967 }
Romain Guy06882f82009-06-10 13:36:04 -07007968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 if (oldHold != newHold) {
7970 try {
7971 if (oldHold != null) {
7972 mBatteryStats.noteStopWakelock(oldHold.mUid,
7973 "window",
7974 BatteryStats.WAKE_TYPE_WINDOW);
7975 }
7976 if (newHold != null) {
7977 mBatteryStats.noteStartWakelock(newHold.mUid,
7978 "window",
7979 BatteryStats.WAKE_TYPE_WINDOW);
7980 }
7981 } catch (RemoteException e) {
7982 }
7983 }
7984 break;
7985 }
Romain Guy06882f82009-06-10 13:36:04 -07007986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 case APP_TRANSITION_TIMEOUT: {
7988 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007989 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007990 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007991 "*** APP TRANSITION TIMEOUT");
7992 mAppTransitionReady = true;
7993 mAppTransitionTimeout = true;
7994 performLayoutAndPlaceSurfacesLocked();
7995 }
7996 }
7997 break;
7998 }
Romain Guy06882f82009-06-10 13:36:04 -07007999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 case PERSIST_ANIMATION_SCALE: {
8001 Settings.System.putFloat(mContext.getContentResolver(),
8002 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8003 Settings.System.putFloat(mContext.getContentResolver(),
8004 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8005 break;
8006 }
Romain Guy06882f82009-06-10 13:36:04 -07008007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008 case FORCE_GC: {
8009 synchronized(mWindowMap) {
8010 if (mAnimationPending) {
8011 // If we are animating, don't do the gc now but
8012 // delay a bit so we don't interrupt the animation.
8013 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8014 2000);
8015 return;
8016 }
8017 // If we are currently rotating the display, it will
8018 // schedule a new message when done.
8019 if (mDisplayFrozen) {
8020 return;
8021 }
8022 mFreezeGcPending = 0;
8023 }
8024 Runtime.getRuntime().gc();
8025 break;
8026 }
Romain Guy06882f82009-06-10 13:36:04 -07008027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 case ENABLE_SCREEN: {
8029 performEnableScreen();
8030 break;
8031 }
Romain Guy06882f82009-06-10 13:36:04 -07008032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008033 case APP_FREEZE_TIMEOUT: {
8034 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008035 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 int i = mAppTokens.size();
8037 while (i > 0) {
8038 i--;
8039 AppWindowToken tok = mAppTokens.get(i);
8040 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008041 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008042 unsetAppFreezingScreenLocked(tok, true, true);
8043 }
8044 }
8045 }
8046 break;
8047 }
Romain Guy06882f82009-06-10 13:36:04 -07008048
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008049 case SEND_NEW_CONFIGURATION: {
8050 removeMessages(SEND_NEW_CONFIGURATION);
8051 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008052 break;
8053 }
Romain Guy06882f82009-06-10 13:36:04 -07008054
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008055 case WINDOWS_CHANGED: {
8056 if (mWindowsChanged) {
8057 synchronized (mWindowMap) {
8058 mWindowsChanged = false;
8059 }
8060 notifyWindowsChanged();
8061 }
8062 break;
8063 }
8064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008065 }
8066 }
8067 }
8068
8069 // -------------------------------------------------------------
8070 // IWindowManager API
8071 // -------------------------------------------------------------
8072
8073 public IWindowSession openSession(IInputMethodClient client,
8074 IInputContext inputContext) {
8075 if (client == null) throw new IllegalArgumentException("null client");
8076 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008077 Session session = new Session(client, inputContext);
8078 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008079 }
8080
8081 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8082 synchronized (mWindowMap) {
8083 // The focus for the client is the window immediately below
8084 // where we would place the input method window.
8085 int idx = findDesiredInputMethodWindowIndexLocked(false);
8086 WindowState imFocus;
8087 if (idx > 0) {
8088 imFocus = (WindowState)mWindows.get(idx-1);
8089 if (imFocus != null) {
8090 if (imFocus.mSession.mClient != null &&
8091 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8092 return true;
8093 }
8094 }
8095 }
8096 }
8097 return false;
8098 }
Romain Guy06882f82009-06-10 13:36:04 -07008099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 // -------------------------------------------------------------
8101 // Internals
8102 // -------------------------------------------------------------
8103
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008104 final WindowState windowForClientLocked(Session session, IWindow client,
8105 boolean throwOnError) {
8106 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008107 }
Romain Guy06882f82009-06-10 13:36:04 -07008108
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008109 final WindowState windowForClientLocked(Session session, IBinder client,
8110 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008111 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008112 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008113 TAG, "Looking up client " + client + ": " + win);
8114 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008115 RuntimeException ex = new IllegalArgumentException(
8116 "Requested window " + client + " does not exist");
8117 if (throwOnError) {
8118 throw ex;
8119 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008120 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121 return null;
8122 }
8123 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008124 RuntimeException ex = new IllegalArgumentException(
8125 "Requested window " + client + " is in session " +
8126 win.mSession + ", not " + session);
8127 if (throwOnError) {
8128 throw ex;
8129 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008130 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 return null;
8132 }
8133
8134 return win;
8135 }
8136
Dianne Hackborna8f60182009-09-01 19:01:50 -07008137 final void rebuildAppWindowListLocked() {
8138 int NW = mWindows.size();
8139 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008140 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008141 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008142
Dianne Hackborna8f60182009-09-01 19:01:50 -07008143 // First remove all existing app windows.
8144 i=0;
8145 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008146 WindowState w = (WindowState)mWindows.get(i);
8147 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008148 WindowState win = (WindowState)mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008149 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008150 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008151 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008152 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008153 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008154 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008155 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8156 && lastWallpaper == i-1) {
8157 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008158 }
8159 i++;
8160 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008161
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008162 // The wallpaper window(s) typically live at the bottom of the stack,
8163 // so skip them before adding app tokens.
8164 lastWallpaper++;
8165 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008166
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008167 // First add all of the exiting app tokens... these are no longer
8168 // in the main app list, but still have windows shown. We put them
8169 // in the back because now that the animation is over we no longer
8170 // will care about them.
8171 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008172 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008173 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8174 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008175
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008176 // And add in the still active app tokens in Z order.
8177 NT = mAppTokens.size();
8178 for (int j=0; j<NT; j++) {
8179 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008180 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008181
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008182 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008183 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008184 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008185 + " windows but added " + i);
8186 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008187 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 private final void assignLayersLocked() {
8190 int N = mWindows.size();
8191 int curBaseLayer = 0;
8192 int curLayer = 0;
8193 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008195 for (i=0; i<N; i++) {
8196 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008197 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8198 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 curLayer += WINDOW_LAYER_MULTIPLIER;
8200 w.mLayer = curLayer;
8201 } else {
8202 curBaseLayer = curLayer = w.mBaseLayer;
8203 w.mLayer = curLayer;
8204 }
8205 if (w.mTargetAppToken != null) {
8206 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
8207 } else if (w.mAppToken != null) {
8208 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
8209 } else {
8210 w.mAnimLayer = w.mLayer;
8211 }
8212 if (w.mIsImWindow) {
8213 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008214 } else if (w.mIsWallpaper) {
8215 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008217 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218 + w.mAnimLayer);
8219 //System.out.println(
8220 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8221 }
8222 }
8223
8224 private boolean mInLayout = false;
8225 private final void performLayoutAndPlaceSurfacesLocked() {
8226 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008227 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 throw new RuntimeException("Recursive call!");
8229 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008230 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008231 return;
8232 }
8233
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008234 if (mWaitingForConfig) {
8235 // Our configuration has changed (most likely rotation), but we
8236 // don't yet have the complete configuration to report to
8237 // applications. Don't do any window layout until we have it.
8238 return;
8239 }
8240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 boolean recoveringMemory = false;
8242 if (mForceRemoves != null) {
8243 recoveringMemory = true;
8244 // Wait a little it for things to settle down, and off we go.
8245 for (int i=0; i<mForceRemoves.size(); i++) {
8246 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008247 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008248 removeWindowInnerLocked(ws.mSession, ws);
8249 }
8250 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008251 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008252 Object tmp = new Object();
8253 synchronized (tmp) {
8254 try {
8255 tmp.wait(250);
8256 } catch (InterruptedException e) {
8257 }
8258 }
8259 }
Romain Guy06882f82009-06-10 13:36:04 -07008260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008261 mInLayout = true;
8262 try {
8263 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07008264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 int i = mPendingRemove.size()-1;
8266 if (i >= 0) {
8267 while (i >= 0) {
8268 WindowState w = mPendingRemove.get(i);
8269 removeWindowInnerLocked(w.mSession, w);
8270 i--;
8271 }
8272 mPendingRemove.clear();
8273
8274 mInLayout = false;
8275 assignLayersLocked();
8276 mLayoutNeeded = true;
8277 performLayoutAndPlaceSurfacesLocked();
8278
8279 } else {
8280 mInLayout = false;
8281 if (mLayoutNeeded) {
8282 requestAnimationLocked(0);
8283 }
8284 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008285 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
8286 mH.removeMessages(H.WINDOWS_CHANGED);
8287 mH.sendMessage(mH.obtainMessage(H.WINDOWS_CHANGED));
8288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289 } catch (RuntimeException e) {
8290 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008291 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008292 }
8293 }
8294
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008295 private final int performLayoutLockedInner() {
8296 if (!mLayoutNeeded) {
8297 return 0;
8298 }
8299
8300 mLayoutNeeded = false;
8301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 final int dw = mDisplay.getWidth();
8303 final int dh = mDisplay.getHeight();
8304
8305 final int N = mWindows.size();
8306 int i;
8307
Joe Onorato8a9b2202010-02-26 18:56:32 -08008308 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008309 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
8310
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008311 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07008312
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008313 int seq = mLayoutSeq+1;
8314 if (seq < 0) seq = 0;
8315 mLayoutSeq = seq;
8316
8317 // First perform layout of any root windows (not attached
8318 // to another window).
8319 int topAttached = -1;
8320 for (i = N-1; i >= 0; i--) {
8321 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008323 // Don't do layout of a window if it is not visible, or
8324 // soon won't be visible, to avoid wasting time and funky
8325 // changes while a window is animating away.
8326 final AppWindowToken atoken = win.mAppToken;
8327 final boolean gone = win.mViewVisibility == View.GONE
8328 || !win.mRelayoutCalled
8329 || win.mRootToken.hidden
8330 || (atoken != null && atoken.hiddenRequested)
8331 || win.mAttachedHidden
8332 || win.mExiting || win.mDestroying;
8333
8334 if (!win.mLayoutAttached) {
8335 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
8336 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8337 + " mLayoutAttached=" + win.mLayoutAttached);
8338 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
8339 + win.mViewVisibility + " mRelayoutCalled="
8340 + win.mRelayoutCalled + " hidden="
8341 + win.mRootToken.hidden + " hiddenRequested="
8342 + (atoken != null && atoken.hiddenRequested)
8343 + " mAttachedHidden=" + win.mAttachedHidden);
8344 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008345
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008346 // If this view is GONE, then skip it -- keep the current
8347 // frame, and let the caller know so they can ignore it
8348 // if they want. (We do the normal layout for INVISIBLE
8349 // windows, since that means "perform layout as normal,
8350 // just don't display").
8351 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008352 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008353 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8354 win.mLayoutSeq = seq;
8355 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8356 + win.mFrame + " mContainingFrame="
8357 + win.mContainingFrame + " mDisplayFrame="
8358 + win.mDisplayFrame);
8359 } else {
8360 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008361 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008363 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008364
8365 // Now perform layout of attached windows, which usually
8366 // depend on the position of the window they are attached to.
8367 // XXX does not deal with windows that are attached to windows
8368 // that are themselves attached.
8369 for (i = topAttached; i >= 0; i--) {
8370 WindowState win = (WindowState) mWindows.get(i);
8371
8372 // If this view is GONE, then skip it -- keep the current
8373 // frame, and let the caller know so they can ignore it
8374 // if they want. (We do the normal layout for INVISIBLE
8375 // windows, since that means "perform layout as normal,
8376 // just don't display").
8377 if (win.mLayoutAttached) {
8378 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
8379 + " mHaveFrame=" + win.mHaveFrame
8380 + " mViewVisibility=" + win.mViewVisibility
8381 + " mRelayoutCalled=" + win.mRelayoutCalled);
8382 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
8383 || !win.mHaveFrame) {
8384 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8385 win.mLayoutSeq = seq;
8386 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8387 + win.mFrame + " mContainingFrame="
8388 + win.mContainingFrame + " mDisplayFrame="
8389 + win.mDisplayFrame);
8390 }
8391 }
8392 }
Jeff Brown349703e2010-06-22 01:27:15 -07008393
8394 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008395 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008396
8397 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008398 }
Romain Guy06882f82009-06-10 13:36:04 -07008399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008400 private final void performLayoutAndPlaceSurfacesLockedInner(
8401 boolean recoveringMemory) {
8402 final long currentTime = SystemClock.uptimeMillis();
8403 final int dw = mDisplay.getWidth();
8404 final int dh = mDisplay.getHeight();
8405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008406 int i;
8407
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008408 if (mFocusMayChange) {
8409 mFocusMayChange = false;
8410 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
8411 }
8412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008413 if (mFxSession == null) {
8414 mFxSession = new SurfaceSession();
8415 }
Romain Guy06882f82009-06-10 13:36:04 -07008416
Joe Onorato8a9b2202010-02-26 18:56:32 -08008417 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418
8419 // Initialize state of exiting tokens.
8420 for (i=mExitingTokens.size()-1; i>=0; i--) {
8421 mExitingTokens.get(i).hasVisible = false;
8422 }
8423
8424 // Initialize state of exiting applications.
8425 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8426 mExitingAppTokens.get(i).hasVisible = false;
8427 }
8428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008429 boolean orientationChangeComplete = true;
8430 Session holdScreen = null;
8431 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05008432 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 boolean focusDisplayed = false;
8434 boolean animating = false;
8435
8436 Surface.openTransaction();
8437 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008438 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008439 int repeats = 0;
8440 int changes = 0;
8441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008442 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008443 repeats++;
8444 if (repeats > 6) {
8445 Slog.w(TAG, "Animation repeat aborted after too many iterations");
8446 mLayoutNeeded = false;
8447 break;
8448 }
8449
8450 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
8451 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
8452 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
8453 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
8454 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
8455 assignLayersLocked();
8456 mLayoutNeeded = true;
8457 }
8458 }
8459 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8460 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8461 if (updateOrientationFromAppTokensLocked()) {
8462 mLayoutNeeded = true;
8463 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
8464 }
8465 }
8466 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
8467 mLayoutNeeded = true;
8468 }
8469 }
8470
8471 // FIRST LOOP: Perform a layout, if needed.
8472 if (repeats < 4) {
8473 changes = performLayoutLockedInner();
8474 if (changes != 0) {
8475 continue;
8476 }
8477 } else {
8478 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8479 changes = 0;
8480 }
8481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 final int transactionSequence = ++mTransactionSequence;
8483
8484 // Update animations of all applications, including those
8485 // associated with exiting/removed apps
8486 boolean tokensAnimating = false;
8487 final int NAT = mAppTokens.size();
8488 for (i=0; i<NAT; i++) {
8489 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
8490 tokensAnimating = true;
8491 }
8492 }
8493 final int NEAT = mExitingAppTokens.size();
8494 for (i=0; i<NEAT; i++) {
8495 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
8496 tokensAnimating = true;
8497 }
8498 }
8499
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008500 // SECOND LOOP: Execute animations and update visibility of windows.
8501
Joe Onorato8a9b2202010-02-26 18:56:32 -08008502 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008503 + transactionSequence + " tokensAnimating="
8504 + tokensAnimating);
8505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008506 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507
8508 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008509 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008510 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008511
8512 mPolicy.beginAnimationLw(dw, dh);
8513
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008514 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008516 for (i=N-1; i>=0; i--) {
8517 WindowState w = (WindowState)mWindows.get(i);
8518
8519 final WindowManager.LayoutParams attrs = w.mAttrs;
8520
8521 if (w.mSurface != null) {
8522 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008523 if (w.commitFinishDrawingLocked(currentTime)) {
8524 if ((w.mAttrs.flags
8525 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008526 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008527 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008528 wallpaperMayChange = true;
8529 }
8530 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008531
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008532 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 if (w.stepAnimationLocked(currentTime, dw, dh)) {
8534 animating = true;
8535 //w.dump(" ");
8536 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008537 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
8538 wallpaperMayChange = true;
8539 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008540
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008541 if (mPolicy.doesForceHide(w, attrs)) {
8542 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08008543 if (DEBUG_VISIBILITY) Slog.v(TAG,
8544 "Animation done that could impact force hide: "
8545 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008546 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008547 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008548 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
8549 forceHiding = true;
8550 }
8551 } else if (mPolicy.canBeForceHidden(w, attrs)) {
8552 boolean changed;
8553 if (forceHiding) {
8554 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08008555 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
8556 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008557 } else {
8558 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08008559 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
8560 "Now policy shown: " + w);
8561 if (changed) {
8562 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008563 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08008564 // Assume we will need to animate. If
8565 // we don't (because the wallpaper will
8566 // stay with the lock screen), then we will
8567 // clean up later.
8568 Animation a = mPolicy.createForceHideEnterAnimation();
8569 if (a != null) {
8570 w.setAnimation(a);
8571 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008572 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08008573 if (mCurrentFocus == null ||
8574 mCurrentFocus.mLayer < w.mLayer) {
8575 // We are showing on to of the current
8576 // focus, so re-evaluate focus to make
8577 // sure it is correct.
8578 mFocusMayChange = true;
8579 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008580 }
8581 }
8582 if (changed && (attrs.flags
8583 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
8584 wallpaperMayChange = true;
8585 }
8586 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008588 mPolicy.animatingWindowLw(w, attrs);
8589 }
8590
8591 final AppWindowToken atoken = w.mAppToken;
8592 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
8593 if (atoken.lastTransactionSequence != transactionSequence) {
8594 atoken.lastTransactionSequence = transactionSequence;
8595 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
8596 atoken.startingDisplayed = false;
8597 }
8598 if ((w.isOnScreen() || w.mAttrs.type
8599 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
8600 && !w.mExiting && !w.mDestroying) {
8601 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008602 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008603 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008604 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008605 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008606 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008607 + " pv=" + w.mPolicyVisibility
8608 + " dp=" + w.mDrawPending
8609 + " cdp=" + w.mCommitDrawPending
8610 + " ah=" + w.mAttachedHidden
8611 + " th=" + atoken.hiddenRequested
8612 + " a=" + w.mAnimating);
8613 }
8614 }
8615 if (w != atoken.startingWindow) {
8616 if (!atoken.freezingScreen || !w.mAppFreezing) {
8617 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008618 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008619 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008620 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 "tokenMayBeDrawn: " + atoken
8622 + " freezingScreen=" + atoken.freezingScreen
8623 + " mAppFreezing=" + w.mAppFreezing);
8624 tokenMayBeDrawn = true;
8625 }
8626 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008627 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 atoken.startingDisplayed = true;
8629 }
8630 }
8631 } else if (w.mReadyToShow) {
8632 w.performShowLocked();
8633 }
8634 }
8635
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008636 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637
8638 if (tokenMayBeDrawn) {
8639 // See if any windows have been drawn, so they (and others
8640 // associated with them) can now be shown.
8641 final int NT = mTokenList.size();
8642 for (i=0; i<NT; i++) {
8643 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
8644 if (wtoken == null) {
8645 continue;
8646 }
8647 if (wtoken.freezingScreen) {
8648 int numInteresting = wtoken.numInterestingWindows;
8649 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008650 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 "allDrawn: " + wtoken
8652 + " interesting=" + numInteresting
8653 + " drawn=" + wtoken.numDrawnWindows);
8654 wtoken.showAllWindowsLocked();
8655 unsetAppFreezingScreenLocked(wtoken, false, true);
8656 orientationChangeComplete = true;
8657 }
8658 } else if (!wtoken.allDrawn) {
8659 int numInteresting = wtoken.numInterestingWindows;
8660 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008661 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008662 "allDrawn: " + wtoken
8663 + " interesting=" + numInteresting
8664 + " drawn=" + wtoken.numDrawnWindows);
8665 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008666 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667
8668 // We can now show all of the drawn windows!
8669 if (!mOpeningApps.contains(wtoken)) {
8670 wtoken.showAllWindowsLocked();
8671 }
8672 }
8673 }
8674 }
8675 }
8676
8677 // If we are ready to perform an app transition, check through
8678 // all of the app tokens to be shown and see if they are ready
8679 // to go.
8680 if (mAppTransitionReady) {
8681 int NN = mOpeningApps.size();
8682 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008683 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008684 "Checking " + NN + " opening apps (frozen="
8685 + mDisplayFrozen + " timeout="
8686 + mAppTransitionTimeout + ")...");
8687 if (!mDisplayFrozen && !mAppTransitionTimeout) {
8688 // If the display isn't frozen, wait to do anything until
8689 // all of the apps are ready. Otherwise just go because
8690 // we'll unfreeze the display when everyone is ready.
8691 for (i=0; i<NN && goodToGo; i++) {
8692 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008693 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694 "Check opening app" + wtoken + ": allDrawn="
8695 + wtoken.allDrawn + " startingDisplayed="
8696 + wtoken.startingDisplayed);
8697 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8698 && !wtoken.startingMoved) {
8699 goodToGo = false;
8700 }
8701 }
8702 }
8703 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008704 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 int transit = mNextAppTransition;
8706 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008707 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008709 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008710 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008711 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008712 mAppTransitionTimeout = false;
8713 mStartingIconInTransition = false;
8714 mSkipAppTransitionAnimation = false;
8715
8716 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8717
Dianne Hackborna8f60182009-09-01 19:01:50 -07008718 // If there are applications waiting to come to the
8719 // top of the stack, now is the time to move their windows.
8720 // (Note that we don't do apps going to the bottom
8721 // here -- we want to keep their windows in the old
8722 // Z-order until the animation completes.)
8723 if (mToTopApps.size() > 0) {
8724 NN = mAppTokens.size();
8725 for (i=0; i<NN; i++) {
8726 AppWindowToken wtoken = mAppTokens.get(i);
8727 if (wtoken.sendingToTop) {
8728 wtoken.sendingToTop = false;
8729 moveAppWindowsLocked(wtoken, NN, false);
8730 }
8731 }
8732 mToTopApps.clear();
8733 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008734
Dianne Hackborn25994b42009-09-04 14:21:19 -07008735 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008736
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008737 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008738 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008739
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008740 // The top-most window will supply the layout params,
8741 // and we will determine it below.
8742 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008743 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008744 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008745
Joe Onorato8a9b2202010-02-26 18:56:32 -08008746 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008747 "New wallpaper target=" + mWallpaperTarget
8748 + ", lower target=" + mLowerWallpaperTarget
8749 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07008750 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008751 // Do a first pass through the tokens for two
8752 // things:
8753 // (1) Determine if both the closing and opening
8754 // app token sets are wallpaper targets, in which
8755 // case special animations are needed
8756 // (since the wallpaper needs to stay static
8757 // behind them).
8758 // (2) Find the layout params of the top-most
8759 // application window in the tokens, which is
8760 // what will control the animation theme.
8761 final int NC = mClosingApps.size();
8762 NN = NC + mOpeningApps.size();
8763 for (i=0; i<NN; i++) {
8764 AppWindowToken wtoken;
8765 int mode;
8766 if (i < NC) {
8767 wtoken = mClosingApps.get(i);
8768 mode = 1;
8769 } else {
8770 wtoken = mOpeningApps.get(i-NC);
8771 mode = 2;
8772 }
8773 if (mLowerWallpaperTarget != null) {
8774 if (mLowerWallpaperTarget.mAppToken == wtoken
8775 || mUpperWallpaperTarget.mAppToken == wtoken) {
8776 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008777 }
8778 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008779 if (wtoken.appFullscreen) {
8780 WindowState ws = wtoken.findMainWindow();
8781 if (ws != null) {
8782 // If this is a compatibility mode
8783 // window, we will always use its anim.
8784 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
8785 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008786 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008787 bestAnimLayer = Integer.MAX_VALUE;
8788 } else if (ws.mLayer > bestAnimLayer) {
8789 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008790 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008791 bestAnimLayer = ws.mLayer;
8792 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07008793 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008794 }
8795 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008796
Dianne Hackborn25994b42009-09-04 14:21:19 -07008797 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008798 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07008799 "Wallpaper animation!");
8800 switch (transit) {
8801 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
8802 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
8803 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
8804 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
8805 break;
8806 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
8807 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
8808 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
8809 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
8810 break;
8811 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008812 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07008813 "New transit: " + transit);
8814 } else if (oldWallpaper != null) {
8815 // We are transitioning from an activity with
8816 // a wallpaper to one without.
8817 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008818 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07008819 "New transit away from wallpaper: " + transit);
8820 } else if (mWallpaperTarget != null) {
8821 // We are transitioning from an activity without
8822 // a wallpaper to now showing the wallpaper
8823 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008824 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07008825 "New transit into wallpaper: " + transit);
8826 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008827
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008828 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
8829 mLastEnterAnimToken = animToken;
8830 mLastEnterAnimParams = animLp;
8831 } else if (mLastEnterAnimParams != null) {
8832 animLp = mLastEnterAnimParams;
8833 mLastEnterAnimToken = null;
8834 mLastEnterAnimParams = null;
8835 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008836
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008837 // If all closing windows are obscured, then there is
8838 // no need to do an animation. This is the case, for
8839 // example, when this transition is being done behind
8840 // the lock screen.
8841 if (!mPolicy.allowAppAnimationsLw()) {
8842 animLp = null;
8843 }
8844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 NN = mOpeningApps.size();
8846 for (i=0; i<NN; i++) {
8847 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008848 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008849 "Now opening app" + wtoken);
8850 wtoken.reportedVisible = false;
8851 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07008852 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008853 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008854 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008855 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 wtoken.showAllWindowsLocked();
8857 }
8858 NN = mClosingApps.size();
8859 for (i=0; i<NN; i++) {
8860 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008861 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008862 "Now closing app" + wtoken);
8863 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07008864 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008865 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008867 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868 // Force the allDrawn flag, because we want to start
8869 // this guy's animations regardless of whether it's
8870 // gotten drawn.
8871 wtoken.allDrawn = true;
8872 }
8873
Dianne Hackborn8b571a82009-09-25 16:09:43 -07008874 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 mOpeningApps.clear();
8877 mClosingApps.clear();
8878
8879 // This has changed the visibility of windows, so perform
8880 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008881 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07008883 if (!moveInputMethodWindowsIfNeededLocked(true)) {
8884 assignLayersLocked();
8885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008886 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008887 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 }
8889 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008890
Dianne Hackborn16064f92010-03-25 00:47:24 -07008891 int adjResult = 0;
8892
Dianne Hackborna8f60182009-09-01 19:01:50 -07008893 if (!animating && mAppTransitionRunning) {
8894 // We have finished the animation of an app transition. To do
8895 // this, we have delayed a lot of operations like showing and
8896 // hiding apps, moving apps in Z-order, etc. The app token list
8897 // reflects the correct Z-order, but the window list may now
8898 // be out of sync with it. So here we will just rebuild the
8899 // entire app window list. Fun!
8900 mAppTransitionRunning = false;
8901 // Clear information about apps that were moving.
8902 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008903
Dianne Hackborna8f60182009-09-01 19:01:50 -07008904 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008905 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07008906 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008907 moveInputMethodWindowsIfNeededLocked(false);
8908 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08008909 // Since the window list has been rebuilt, focus might
8910 // have to be recomputed since the actual order of windows
8911 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008912 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008913 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008914
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008915 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008916 // At this point, there was a window with a wallpaper that
8917 // was force hiding other windows behind it, but now it
8918 // is going away. This may be simple -- just animate
8919 // away the wallpaper and its window -- or it may be
8920 // hard -- the wallpaper now needs to be shown behind
8921 // something that was hidden.
8922 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008923 if (mLowerWallpaperTarget != null
8924 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008925 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008926 "wallpaperForceHiding changed with lower="
8927 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008928 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008929 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
8930 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
8931 if (mLowerWallpaperTarget.mAppToken.hidden) {
8932 // The lower target has become hidden before we
8933 // actually started the animation... let's completely
8934 // re-evaluate everything.
8935 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008936 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008937 }
8938 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07008939 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008940 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008941 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008942 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008943 + " NEW: " + mWallpaperTarget
8944 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008945 if (mLowerWallpaperTarget == null) {
8946 // Whoops, we don't need a special wallpaper animation.
8947 // Clear them out.
8948 forceHiding = false;
8949 for (i=N-1; i>=0; i--) {
8950 WindowState w = (WindowState)mWindows.get(i);
8951 if (w.mSurface != null) {
8952 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07008953 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008954 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008955 forceHiding = true;
8956 } else if (mPolicy.canBeForceHidden(w, attrs)) {
8957 if (!w.mAnimating) {
8958 // We set the animation above so it
8959 // is not yet running.
8960 w.clearAnimation();
8961 }
8962 }
8963 }
8964 }
8965 }
8966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008967
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008968 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008969 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008970 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07008971 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008972 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008973
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008974 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008975 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008976 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008977 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008978 assignLayersLocked();
8979 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008980 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008981 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008982 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008983 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008984
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008985 if (mFocusMayChange) {
8986 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008987 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008988 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008989 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008990 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008991 }
8992
8993 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008994 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008995 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008996
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008997 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
8998 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008999
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009000 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009001
9002 // THIRD LOOP: Update the surfaces of all windows.
9003
9004 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9005
9006 boolean obscured = false;
9007 boolean blurring = false;
9008 boolean dimming = false;
9009 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009010 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009011 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009012
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009013 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 for (i=N-1; i>=0; i--) {
9016 WindowState w = (WindowState)mWindows.get(i);
9017
9018 boolean displayed = false;
9019 final WindowManager.LayoutParams attrs = w.mAttrs;
9020 final int attrFlags = attrs.flags;
9021
9022 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009023 // XXX NOTE: The logic here could be improved. We have
9024 // the decision about whether to resize a window separated
9025 // from whether to hide the surface. This can cause us to
9026 // resize a surface even if we are going to hide it. You
9027 // can see this by (1) holding device in landscape mode on
9028 // home screen; (2) tapping browser icon (device will rotate
9029 // to landscape; (3) tap home. The wallpaper will be resized
9030 // in step 2 but then immediately hidden, causing us to
9031 // have to resize and then redraw it again in step 3. It
9032 // would be nice to figure out how to avoid this, but it is
9033 // difficult because we do need to resize surfaces in some
9034 // cases while they are hidden such as when first showing a
9035 // window.
9036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009038 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 TAG, "Placing surface #" + i + " " + w.mSurface
9040 + ": new=" + w.mShownFrame + ", old="
9041 + w.mLastShownFrame);
9042
9043 boolean resize;
9044 int width, height;
9045 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9046 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9047 w.mLastRequestedHeight != w.mRequestedHeight;
9048 // for a scaled surface, we just want to use
9049 // the requested size.
9050 width = w.mRequestedWidth;
9051 height = w.mRequestedHeight;
9052 w.mLastRequestedWidth = width;
9053 w.mLastRequestedHeight = height;
9054 w.mLastShownFrame.set(w.mShownFrame);
9055 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009056 if (SHOW_TRANSACTIONS) logSurface(w,
9057 "POS " + w.mShownFrame.left
9058 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009059 w.mSurfaceX = w.mShownFrame.left;
9060 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9062 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009063 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009064 if (!recoveringMemory) {
9065 reclaimSomeSurfaceMemoryLocked(w, "position");
9066 }
9067 }
9068 } else {
9069 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9070 width = w.mShownFrame.width();
9071 height = w.mShownFrame.height();
9072 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009073 }
9074
9075 if (resize) {
9076 if (width < 1) width = 1;
9077 if (height < 1) height = 1;
9078 if (w.mSurface != null) {
9079 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009080 if (SHOW_TRANSACTIONS) logSurface(w,
9081 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009082 + w.mShownFrame.top + " SIZE "
9083 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009084 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009085 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009086 w.mSurfaceW = width;
9087 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009088 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009089 w.mSurfaceX = w.mShownFrame.left;
9090 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009091 w.mSurface.setPosition(w.mShownFrame.left,
9092 w.mShownFrame.top);
9093 } catch (RuntimeException e) {
9094 // If something goes wrong with the surface (such
9095 // as running out of memory), don't take down the
9096 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009097 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009098 + "size=(" + width + "x" + height
9099 + "), pos=(" + w.mShownFrame.left
9100 + "," + w.mShownFrame.top + ")", e);
9101 if (!recoveringMemory) {
9102 reclaimSomeSurfaceMemoryLocked(w, "size");
9103 }
9104 }
9105 }
9106 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009107 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 w.mContentInsetsChanged =
9109 !w.mLastContentInsets.equals(w.mContentInsets);
9110 w.mVisibleInsetsChanged =
9111 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009112 boolean configChanged =
9113 w.mConfiguration != mCurConfiguration
9114 && (w.mConfiguration == null
9115 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009116 if (DEBUG_CONFIGURATION && configChanged) {
9117 Slog.v(TAG, "Win " + w + " config changed: "
9118 + mCurConfiguration);
9119 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009120 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009121 + ": configChanged=" + configChanged
9122 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -07009123 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009124 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009125 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009126 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009127 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009128 w.mLastFrame.set(w.mFrame);
9129 w.mLastContentInsets.set(w.mContentInsets);
9130 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009131 // If the screen is currently frozen, then keep
9132 // it frozen until this window draws at its new
9133 // orientation.
9134 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009135 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009136 "Resizing while display frozen: " + w);
9137 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009138 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009139 mWindowsFreezingScreen = true;
9140 // XXX should probably keep timeout from
9141 // when we first froze the display.
9142 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9143 mH.sendMessageDelayed(mH.obtainMessage(
9144 H.WINDOW_FREEZE_TIMEOUT), 2000);
9145 }
9146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009147 // If the orientation is changing, then we need to
9148 // hold off on unfreezing the display until this
9149 // window has been redrawn; to do that, we need
9150 // to go through the process of getting informed
9151 // by the application when it has finished drawing.
9152 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009153 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 "Orientation start waiting for draw in "
9155 + w + ", surface " + w.mSurface);
9156 w.mDrawPending = true;
9157 w.mCommitDrawPending = false;
9158 w.mReadyToShow = false;
9159 if (w.mAppToken != null) {
9160 w.mAppToken.allDrawn = false;
9161 }
9162 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009163 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009164 "Resizing window " + w + " to " + w.mFrame);
9165 mResizingWindows.add(w);
9166 } else if (w.mOrientationChanging) {
9167 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009168 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009169 "Orientation not waiting for draw in "
9170 + w + ", surface " + w.mSurface);
9171 w.mOrientationChanging = false;
9172 }
9173 }
9174 }
9175
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009176 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177 if (!w.mLastHidden) {
9178 //dump();
Dianne Hackborn5943c202010-04-12 21:36:49 -07009179 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Window hiding: waitingToShow="
9180 + w.mRootToken.waitingToShow + " polvis="
9181 + w.mPolicyVisibility + " atthid="
9182 + w.mAttachedHidden + " tokhid="
9183 + w.mRootToken.hidden + " vis="
9184 + w.mViewVisibility);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009185 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009186 if (SHOW_TRANSACTIONS) logSurface(w,
9187 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009188 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009189 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009190 try {
9191 w.mSurface.hide();
9192 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009193 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009194 }
9195 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009196 mInputMonitor.windowIsBecomingInvisibleLw(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009197 }
9198 // If we are waiting for this window to handle an
9199 // orientation change, well, it is hidden, so
9200 // doesn't really matter. Note that this does
9201 // introduce a potential glitch if the window
9202 // becomes unhidden before it has drawn for the
9203 // new orientation.
9204 if (w.mOrientationChanging) {
9205 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009206 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009207 "Orientation change skips hidden " + w);
9208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009209 } else if (w.mLastLayer != w.mAnimLayer
9210 || w.mLastAlpha != w.mShownAlpha
9211 || w.mLastDsDx != w.mDsDx
9212 || w.mLastDtDx != w.mDtDx
9213 || w.mLastDsDy != w.mDsDy
9214 || w.mLastDtDy != w.mDtDy
9215 || w.mLastHScale != w.mHScale
9216 || w.mLastVScale != w.mVScale
9217 || w.mLastHidden) {
9218 displayed = true;
9219 w.mLastAlpha = w.mShownAlpha;
9220 w.mLastLayer = w.mAnimLayer;
9221 w.mLastDsDx = w.mDsDx;
9222 w.mLastDtDx = w.mDtDx;
9223 w.mLastDsDy = w.mDsDy;
9224 w.mLastDtDy = w.mDtDy;
9225 w.mLastHScale = w.mHScale;
9226 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009227 if (SHOW_TRANSACTIONS) logSurface(w,
9228 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009229 + " matrix=[" + (w.mDsDx*w.mHScale)
9230 + "," + (w.mDtDx*w.mVScale)
9231 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009232 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009233 if (w.mSurface != null) {
9234 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009235 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009237 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009238 w.mSurface.setLayer(w.mAnimLayer);
9239 w.mSurface.setMatrix(
9240 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
9241 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
9242 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009243 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 if (!recoveringMemory) {
9245 reclaimSomeSurfaceMemoryLocked(w, "update");
9246 }
9247 }
9248 }
9249
9250 if (w.mLastHidden && !w.mDrawPending
9251 && !w.mCommitDrawPending
9252 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009253 if (SHOW_TRANSACTIONS) logSurface(w,
9254 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009255 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009256 + " during relayout");
9257 if (showSurfaceRobustlyLocked(w)) {
9258 w.mHasDrawn = true;
9259 w.mLastHidden = false;
9260 } else {
9261 w.mOrientationChanging = false;
9262 }
9263 }
9264 if (w.mSurface != null) {
9265 w.mToken.hasVisible = true;
9266 }
9267 } else {
9268 displayed = true;
9269 }
9270
9271 if (displayed) {
9272 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08009273 if (attrs.width == LayoutParams.MATCH_PARENT
9274 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009275 covered = true;
9276 }
9277 }
9278 if (w.mOrientationChanging) {
9279 if (w.mDrawPending || w.mCommitDrawPending) {
9280 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009281 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 "Orientation continue waiting for draw in " + w);
9283 } else {
9284 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009285 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009286 "Orientation change complete in " + w);
9287 }
9288 }
9289 w.mToken.hasVisible = true;
9290 }
9291 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009292 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009293 "Orientation change skips hidden " + w);
9294 w.mOrientationChanging = false;
9295 }
9296
9297 final boolean canBeSeen = w.isDisplayedLw();
9298
9299 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
9300 focusDisplayed = true;
9301 }
9302
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07009303 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009305 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009306 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 if (w.mSurface != null) {
9308 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
9309 holdScreen = w.mSession;
9310 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009311 if (!syswin && w.mAttrs.screenBrightness >= 0
9312 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009313 screenBrightness = w.mAttrs.screenBrightness;
9314 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009315 if (!syswin && w.mAttrs.buttonBrightness >= 0
9316 && buttonBrightness < 0) {
9317 buttonBrightness = w.mAttrs.buttonBrightness;
9318 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05009319 if (canBeSeen
9320 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
9321 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
9322 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009323 syswin = true;
9324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009326
Dianne Hackborn25994b42009-09-04 14:21:19 -07009327 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
9328 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009329 // This window completely covers everything behind it,
9330 // so we want to leave all of them as unblurred (for
9331 // performance reasons).
9332 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009333 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009334 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009335 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009336 obscured = true;
9337 if (mBackgroundFillerSurface == null) {
9338 try {
9339 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009340 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009341 0, dw, dh,
9342 PixelFormat.OPAQUE,
9343 Surface.FX_SURFACE_NORMAL);
9344 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009345 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009346 }
9347 }
9348 try {
9349 mBackgroundFillerSurface.setPosition(0, 0);
9350 mBackgroundFillerSurface.setSize(dw, dh);
9351 // Using the same layer as Dim because they will never be shown at the
9352 // same time.
9353 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
9354 mBackgroundFillerSurface.show();
9355 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009356 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009357 }
9358 backgroundFillerShown = true;
9359 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009360 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009361 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009362 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 + ": blurring=" + blurring
9364 + " obscured=" + obscured
9365 + " displayed=" + displayed);
9366 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
9367 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009368 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009370 if (mDimAnimator == null) {
9371 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009372 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009373 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009374 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 }
9377 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
9378 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009379 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009382 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009383 + mBlurSurface + ": CREATE");
9384 try {
Romain Guy06882f82009-06-10 13:36:04 -07009385 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009386 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387 -1, 16, 16,
9388 PixelFormat.OPAQUE,
9389 Surface.FX_SURFACE_BLUR);
9390 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009391 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009392 }
9393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009395 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
9396 + mBlurSurface + ": pos=(0,0) (" +
9397 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 mBlurSurface.setPosition(0, 0);
9399 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009400 mBlurSurface.setLayer(w.mAnimLayer-2);
9401 if (!mBlurShown) {
9402 try {
9403 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
9404 + mBlurSurface + ": SHOW");
9405 mBlurSurface.show();
9406 } catch (RuntimeException e) {
9407 Slog.w(TAG, "Failure showing blur surface", e);
9408 }
9409 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009410 }
9411 }
9412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 }
9414 }
9415 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009416
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07009417 if (obscuredChanged && mWallpaperTarget == w) {
9418 // This is the wallpaper target and its obscured state
9419 // changed... make sure the current wallaper's visibility
9420 // has been updated accordingly.
9421 updateWallpaperVisibilityLocked();
9422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009423 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009424
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009425 if (backgroundFillerShown == false && mBackgroundFillerShown) {
9426 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009427 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009428 try {
9429 mBackgroundFillerSurface.hide();
9430 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009431 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009432 }
9433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009435 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009436 animating |= mDimAnimator.updateSurface(dimming, currentTime,
9437 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 }
Romain Guy06882f82009-06-10 13:36:04 -07009439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009441 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 + ": HIDE");
9443 try {
9444 mBlurSurface.hide();
9445 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009446 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009447 }
9448 mBlurShown = false;
9449 }
9450
Joe Onorato8a9b2202010-02-26 18:56:32 -08009451 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009452 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009453 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 }
9455
9456 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -07009457
Joe Onorato8a9b2202010-02-26 18:56:32 -08009458 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 "With display frozen, orientationChangeComplete="
9460 + orientationChangeComplete);
9461 if (orientationChangeComplete) {
9462 if (mWindowsFreezingScreen) {
9463 mWindowsFreezingScreen = false;
9464 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9465 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009466 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009467 }
Romain Guy06882f82009-06-10 13:36:04 -07009468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469 i = mResizingWindows.size();
9470 if (i > 0) {
9471 do {
9472 i--;
9473 WindowState win = mResizingWindows.get(i);
9474 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009475 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
9476 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009477 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009478 boolean configChanged =
9479 win.mConfiguration != mCurConfiguration
9480 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009481 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
9482 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
9483 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009484 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009485 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009486 + " / " + mCurConfiguration + " / 0x"
9487 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009488 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009489 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 win.mClient.resized(win.mFrame.width(),
9491 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009492 win.mLastVisibleInsets, win.mDrawPending,
9493 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 win.mContentInsetsChanged = false;
9495 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009496 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 } catch (RemoteException e) {
9498 win.mOrientationChanging = false;
9499 }
9500 } while (i > 0);
9501 mResizingWindows.clear();
9502 }
Romain Guy06882f82009-06-10 13:36:04 -07009503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009504 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009505 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009506 i = mDestroySurface.size();
9507 if (i > 0) {
9508 do {
9509 i--;
9510 WindowState win = mDestroySurface.get(i);
9511 win.mDestroying = false;
9512 if (mInputMethodWindow == win) {
9513 mInputMethodWindow = null;
9514 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009515 if (win == mWallpaperTarget) {
9516 wallpaperDestroyed = true;
9517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 win.destroySurfaceLocked();
9519 } while (i > 0);
9520 mDestroySurface.clear();
9521 }
9522
9523 // Time to remove any exiting tokens?
9524 for (i=mExitingTokens.size()-1; i>=0; i--) {
9525 WindowToken token = mExitingTokens.get(i);
9526 if (!token.hasVisible) {
9527 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009528 if (token.windowType == TYPE_WALLPAPER) {
9529 mWallpaperTokens.remove(token);
9530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 }
9532 }
9533
9534 // Time to remove any exiting applications?
9535 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9536 AppWindowToken token = mExitingAppTokens.get(i);
9537 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009538 // Make sure there is no animation running on this token,
9539 // so any windows associated with it will be removed as
9540 // soon as their animations are complete
9541 token.animation = null;
9542 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 mAppTokens.remove(token);
9544 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009545 if (mLastEnterAnimToken == token) {
9546 mLastEnterAnimToken = null;
9547 mLastEnterAnimParams = null;
9548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 }
9550 }
9551
Dianne Hackborna8f60182009-09-01 19:01:50 -07009552 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009553
Dianne Hackborna8f60182009-09-01 19:01:50 -07009554 if (!animating && mAppTransitionRunning) {
9555 // We have finished the animation of an app transition. To do
9556 // this, we have delayed a lot of operations like showing and
9557 // hiding apps, moving apps in Z-order, etc. The app token list
9558 // reflects the correct Z-order, but the window list may now
9559 // be out of sync with it. So here we will just rebuild the
9560 // entire app window list. Fun!
9561 mAppTransitionRunning = false;
9562 needRelayout = true;
9563 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -07009564 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009565 // Clear information about apps that were moving.
9566 mToBottomApps.clear();
9567 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009569 if (focusDisplayed) {
9570 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9571 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009572 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009573 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009574 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009575 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009576 requestAnimationLocked(0);
9577 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
9579 }
Dianne Hackbornce73c1e2010-04-12 23:11:38 -07009580
9581 if (DEBUG_FREEZE) Slog.v(TAG, "Layout: mDisplayFrozen=" + mDisplayFrozen
9582 + " holdScreen=" + holdScreen);
9583 if (!mDisplayFrozen) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009584 setHoldScreenLocked(holdScreen != null);
Dianne Hackbornce73c1e2010-04-12 23:11:38 -07009585 if (screenBrightness < 0 || screenBrightness > 1.0f) {
9586 mPowerManager.setScreenBrightnessOverride(-1);
9587 } else {
9588 mPowerManager.setScreenBrightnessOverride((int)
9589 (screenBrightness * Power.BRIGHTNESS_ON));
9590 }
9591 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
9592 mPowerManager.setButtonBrightnessOverride(-1);
9593 } else {
9594 mPowerManager.setButtonBrightnessOverride((int)
9595 (buttonBrightness * Power.BRIGHTNESS_ON));
9596 }
9597 if (holdScreen != mHoldingScreenOn) {
9598 mHoldingScreenOn = holdScreen;
9599 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
9600 mH.sendMessage(m);
9601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009603
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009604 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009605 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009606 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
9607 LocalPowerManager.BUTTON_EVENT, true);
9608 mTurnOnScreen = false;
9609 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009610
9611 // Check to see if we are now in a state where the screen should
9612 // be enabled, because the window obscured flags have changed.
9613 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009614 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009615
9616 /**
9617 * Must be called with the main window manager lock held.
9618 */
9619 void setHoldScreenLocked(boolean holding) {
9620 boolean state = mHoldingScreenWakeLock.isHeld();
9621 if (holding != state) {
9622 if (holding) {
9623 mHoldingScreenWakeLock.acquire();
9624 } else {
9625 mPolicy.screenOnStoppedLw();
9626 mHoldingScreenWakeLock.release();
9627 }
9628 }
9629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630
9631 void requestAnimationLocked(long delay) {
9632 if (!mAnimationPending) {
9633 mAnimationPending = true;
9634 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
9635 }
9636 }
Romain Guy06882f82009-06-10 13:36:04 -07009637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009638 /**
9639 * Have the surface flinger show a surface, robustly dealing with
9640 * error conditions. In particular, if there is not enough memory
9641 * to show the surface, then we will try to get rid of other surfaces
9642 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -07009643 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 * @return Returns true if the surface was successfully shown.
9645 */
9646 boolean showSurfaceRobustlyLocked(WindowState win) {
9647 try {
9648 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009649 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009651 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009652 if (DEBUG_VISIBILITY) Slog.v(TAG,
9653 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009654 win.mTurnOnScreen = false;
9655 mTurnOnScreen = true;
9656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 }
9658 return true;
9659 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009660 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 }
Romain Guy06882f82009-06-10 13:36:04 -07009662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009663 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -07009664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009665 return false;
9666 }
Romain Guy06882f82009-06-10 13:36:04 -07009667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009668 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
9669 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -07009670
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009671 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009672 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 if (mForceRemoves == null) {
9675 mForceRemoves = new ArrayList<WindowState>();
9676 }
Romain Guy06882f82009-06-10 13:36:04 -07009677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009678 long callingIdentity = Binder.clearCallingIdentity();
9679 try {
9680 // There was some problem... first, do a sanity check of the
9681 // window list to make sure we haven't left any dangling surfaces
9682 // around.
9683 int N = mWindows.size();
9684 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009685 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 for (int i=0; i<N; i++) {
9687 WindowState ws = (WindowState)mWindows.get(i);
9688 if (ws.mSurface != null) {
9689 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009690 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009691 + ws + " surface=" + ws.mSurface
9692 + " token=" + win.mToken
9693 + " pid=" + ws.mSession.mPid
9694 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009695 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07009696 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009697 ws.mSurface = null;
9698 mForceRemoves.add(ws);
9699 i--;
9700 N--;
9701 leakedSurface = true;
9702 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009703 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704 + ws + " surface=" + ws.mSurface
9705 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009706 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07009707 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009708 ws.mSurface = null;
9709 leakedSurface = true;
9710 }
9711 }
9712 }
Romain Guy06882f82009-06-10 13:36:04 -07009713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009714 boolean killedApps = false;
9715 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009716 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009717 SparseIntArray pidCandidates = new SparseIntArray();
9718 for (int i=0; i<N; i++) {
9719 WindowState ws = (WindowState)mWindows.get(i);
9720 if (ws.mSurface != null) {
9721 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
9722 }
9723 }
9724 if (pidCandidates.size() > 0) {
9725 int[] pids = new int[pidCandidates.size()];
9726 for (int i=0; i<pids.length; i++) {
9727 pids[i] = pidCandidates.keyAt(i);
9728 }
9729 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07009730 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731 killedApps = true;
9732 }
9733 } catch (RemoteException e) {
9734 }
9735 }
9736 }
Romain Guy06882f82009-06-10 13:36:04 -07009737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 if (leakedSurface || killedApps) {
9739 // We managed to reclaim some memory, so get rid of the trouble
9740 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009741 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009742 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009743 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07009744 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 win.mSurface = null;
9746 }
Romain Guy06882f82009-06-10 13:36:04 -07009747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 try {
9749 win.mClient.dispatchGetNewSurface();
9750 } catch (RemoteException e) {
9751 }
9752 }
9753 } finally {
9754 Binder.restoreCallingIdentity(callingIdentity);
9755 }
9756 }
Romain Guy06882f82009-06-10 13:36:04 -07009757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 private boolean updateFocusedWindowLocked(int mode) {
9759 WindowState newFocus = computeFocusedWindowLocked();
9760 if (mCurrentFocus != newFocus) {
9761 // This check makes sure that we don't already have the focus
9762 // change message pending.
9763 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9764 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009765 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9767 final WindowState oldFocus = mCurrentFocus;
9768 mCurrentFocus = newFocus;
9769 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 final WindowState imWindow = mInputMethodWindow;
9772 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009773 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009774 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009775 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
9776 mLayoutNeeded = true;
9777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009778 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
9779 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009780 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9781 // Client will do the layout, but we need to assign layers
9782 // for handleNewWindowLocked() below.
9783 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009784 }
9785 }
Jeff Brown349703e2010-06-22 01:27:15 -07009786
9787 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9788 // If we defer assigning layers, then the caller is responsible for
9789 // doing this part.
9790 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009792 return true;
9793 }
9794 return false;
9795 }
Jeff Brown349703e2010-06-22 01:27:15 -07009796
9797 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009798 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07009799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009800
9801 private WindowState computeFocusedWindowLocked() {
9802 WindowState result = null;
9803 WindowState win;
9804
9805 int i = mWindows.size() - 1;
9806 int nextAppIndex = mAppTokens.size()-1;
9807 WindowToken nextApp = nextAppIndex >= 0
9808 ? mAppTokens.get(nextAppIndex) : null;
9809
9810 while (i >= 0) {
9811 win = (WindowState)mWindows.get(i);
9812
Joe Onorato8a9b2202010-02-26 18:56:32 -08009813 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 TAG, "Looking for focus: " + i
9815 + " = " + win
9816 + ", flags=" + win.mAttrs.flags
9817 + ", canReceive=" + win.canReceiveKeys());
9818
9819 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009821 // If this window's application has been removed, just skip it.
9822 if (thisApp != null && thisApp.removed) {
9823 i--;
9824 continue;
9825 }
Romain Guy06882f82009-06-10 13:36:04 -07009826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009827 // If there is a focused app, don't allow focus to go to any
9828 // windows below it. If this is an application window, step
9829 // through the app tokens until we find its app.
9830 if (thisApp != null && nextApp != null && thisApp != nextApp
9831 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
9832 int origAppIndex = nextAppIndex;
9833 while (nextAppIndex > 0) {
9834 if (nextApp == mFocusedApp) {
9835 // Whoops, we are below the focused app... no focus
9836 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009837 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009838 TAG, "Reached focused app: " + mFocusedApp);
9839 return null;
9840 }
9841 nextAppIndex--;
9842 nextApp = mAppTokens.get(nextAppIndex);
9843 if (nextApp == thisApp) {
9844 break;
9845 }
9846 }
9847 if (thisApp != nextApp) {
9848 // Uh oh, the app token doesn't exist! This shouldn't
9849 // happen, but if it does we can get totally hosed...
9850 // so restart at the original app.
9851 nextAppIndex = origAppIndex;
9852 nextApp = mAppTokens.get(nextAppIndex);
9853 }
9854 }
9855
9856 // Dispatch to this window if it is wants key events.
9857 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009858 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 TAG, "Found focus @ " + i + " = " + win);
9860 result = win;
9861 break;
9862 }
9863
9864 i--;
9865 }
9866
9867 return result;
9868 }
9869
9870 private void startFreezingDisplayLocked() {
9871 if (mDisplayFrozen) {
9872 return;
9873 }
Romain Guy06882f82009-06-10 13:36:04 -07009874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009875 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009877 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009878 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 if (mFreezeGcPending != 0) {
9880 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009881 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 mH.removeMessages(H.FORCE_GC);
9883 Runtime.getRuntime().gc();
9884 mFreezeGcPending = now;
9885 }
9886 } else {
9887 mFreezeGcPending = now;
9888 }
Romain Guy06882f82009-06-10 13:36:04 -07009889
Dianne Hackbornce73c1e2010-04-12 23:11:38 -07009890 if (DEBUG_FREEZE) Slog.v(TAG, "*** FREEZING DISPLAY", new RuntimeException());
9891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -07009893
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009894 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -07009895
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009896 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
9897 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009898 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009899 mAppTransitionReady = true;
9900 }
Romain Guy06882f82009-06-10 13:36:04 -07009901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009902 if (PROFILE_ORIENTATION) {
9903 File file = new File("/data/system/frozen");
9904 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9905 }
9906 Surface.freezeDisplay(0);
9907 }
Romain Guy06882f82009-06-10 13:36:04 -07009908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 private void stopFreezingDisplayLocked() {
9910 if (!mDisplayFrozen) {
9911 return;
9912 }
Romain Guy06882f82009-06-10 13:36:04 -07009913
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009914 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
9915 return;
9916 }
9917
Dianne Hackbornce73c1e2010-04-12 23:11:38 -07009918 if (DEBUG_FREEZE) Slog.v(TAG, "*** UNFREEZING DISPLAY", new RuntimeException());
9919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009920 mDisplayFrozen = false;
9921 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
9922 if (PROFILE_ORIENTATION) {
9923 Debug.stopMethodTracing();
9924 }
9925 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -07009926
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009927 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009928
Christopher Tateb696aee2010-04-02 19:08:30 -07009929 // While the display is frozen we don't re-compute the orientation
9930 // to avoid inconsistent states. However, something interesting
9931 // could have actually changed during that time so re-evaluate it
9932 // now to catch that.
9933 if (updateOrientationFromAppTokensLocked()) {
9934 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9935 }
9936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 // A little kludge: a lot could have happened while the
9938 // display was frozen, so now that we are coming back we
9939 // do a gc so that any remote references the system
9940 // processes holds on others can be released if they are
9941 // no longer needed.
9942 mH.removeMessages(H.FORCE_GC);
9943 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9944 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009946 mScreenFrozenLock.release();
9947 }
Romain Guy06882f82009-06-10 13:36:04 -07009948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009949 @Override
9950 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9951 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
9952 != PackageManager.PERMISSION_GRANTED) {
9953 pw.println("Permission Denial: can't dump WindowManager from from pid="
9954 + Binder.getCallingPid()
9955 + ", uid=" + Binder.getCallingUid());
9956 return;
9957 }
Romain Guy06882f82009-06-10 13:36:04 -07009958
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009959 pw.println("Input Dispatcher State:");
9960 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -08009961 pw.println(" ");
9962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009963 synchronized(mWindowMap) {
9964 pw.println("Current Window Manager state:");
9965 for (int i=mWindows.size()-1; i>=0; i--) {
9966 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009967 pw.print(" Window #"); pw.print(i); pw.print(' ');
9968 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009969 w.dump(pw, " ");
9970 }
9971 if (mInputMethodDialogs.size() > 0) {
9972 pw.println(" ");
9973 pw.println(" Input method dialogs:");
9974 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
9975 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009976 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009977 }
9978 }
9979 if (mPendingRemove.size() > 0) {
9980 pw.println(" ");
9981 pw.println(" Remove pending for:");
9982 for (int i=mPendingRemove.size()-1; i>=0; i--) {
9983 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009984 pw.print(" Remove #"); pw.print(i); pw.print(' ');
9985 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009986 w.dump(pw, " ");
9987 }
9988 }
9989 if (mForceRemoves != null && mForceRemoves.size() > 0) {
9990 pw.println(" ");
9991 pw.println(" Windows force removing:");
9992 for (int i=mForceRemoves.size()-1; i>=0; i--) {
9993 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009994 pw.print(" Removing #"); pw.print(i); pw.print(' ');
9995 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 w.dump(pw, " ");
9997 }
9998 }
9999 if (mDestroySurface.size() > 0) {
10000 pw.println(" ");
10001 pw.println(" Windows waiting to destroy their surface:");
10002 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10003 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010004 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
10005 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 w.dump(pw, " ");
10007 }
10008 }
10009 if (mLosingFocus.size() > 0) {
10010 pw.println(" ");
10011 pw.println(" Windows losing focus:");
10012 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10013 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010014 pw.print(" Losing #"); pw.print(i); pw.print(' ');
10015 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 w.dump(pw, " ");
10017 }
10018 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010019 if (mResizingWindows.size() > 0) {
10020 pw.println(" ");
10021 pw.println(" Windows waiting to resize:");
10022 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10023 WindowState w = mResizingWindows.get(i);
10024 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
10025 pw.print(w); pw.println(":");
10026 w.dump(pw, " ");
10027 }
10028 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 if (mSessions.size() > 0) {
10030 pw.println(" ");
10031 pw.println(" All active sessions:");
10032 Iterator<Session> it = mSessions.iterator();
10033 while (it.hasNext()) {
10034 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010035 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 s.dump(pw, " ");
10037 }
10038 }
10039 if (mTokenMap.size() > 0) {
10040 pw.println(" ");
10041 pw.println(" All tokens:");
10042 Iterator<WindowToken> it = mTokenMap.values().iterator();
10043 while (it.hasNext()) {
10044 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010045 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 token.dump(pw, " ");
10047 }
10048 }
10049 if (mTokenList.size() > 0) {
10050 pw.println(" ");
10051 pw.println(" Window token list:");
10052 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010053 pw.print(" #"); pw.print(i); pw.print(": ");
10054 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010055 }
10056 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010057 if (mWallpaperTokens.size() > 0) {
10058 pw.println(" ");
10059 pw.println(" Wallpaper tokens:");
10060 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10061 WindowToken token = mWallpaperTokens.get(i);
10062 pw.print(" Wallpaper #"); pw.print(i);
10063 pw.print(' '); pw.print(token); pw.println(':');
10064 token.dump(pw, " ");
10065 }
10066 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 if (mAppTokens.size() > 0) {
10068 pw.println(" ");
10069 pw.println(" Application tokens in Z order:");
10070 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010071 pw.print(" App #"); pw.print(i); pw.print(": ");
10072 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 }
10074 }
10075 if (mFinishedStarting.size() > 0) {
10076 pw.println(" ");
10077 pw.println(" Finishing start of application tokens:");
10078 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10079 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010080 pw.print(" Finished Starting #"); pw.print(i);
10081 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010082 token.dump(pw, " ");
10083 }
10084 }
10085 if (mExitingTokens.size() > 0) {
10086 pw.println(" ");
10087 pw.println(" Exiting tokens:");
10088 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10089 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010090 pw.print(" Exiting #"); pw.print(i);
10091 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010092 token.dump(pw, " ");
10093 }
10094 }
10095 if (mExitingAppTokens.size() > 0) {
10096 pw.println(" ");
10097 pw.println(" Exiting application tokens:");
10098 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10099 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010100 pw.print(" Exiting App #"); pw.print(i);
10101 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102 token.dump(pw, " ");
10103 }
10104 }
10105 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010106 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10107 pw.print(" mLastFocus="); pw.println(mLastFocus);
10108 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10109 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
10110 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010111 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010112 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10113 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10114 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10115 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010116 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10117 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10118 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010119 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10120 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
10121 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
10122 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010123 if (mDimAnimator != null) {
10124 mDimAnimator.printTo(pw);
10125 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080010126 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010127 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010128 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070010129 pw.print(mInputMethodAnimLayerAdjustment);
10130 pw.print(" mWallpaperAnimLayerAdjustment=");
10131 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010132 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10133 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010134 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
10135 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010136 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
10137 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010138 pw.print(" mRotation="); pw.print(mRotation);
10139 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
10140 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
10141 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
10142 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10143 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
10144 pw.print(" mNextAppTransition=0x");
10145 pw.print(Integer.toHexString(mNextAppTransition));
10146 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070010147 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010148 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010149 if (mNextAppTransitionPackage != null) {
10150 pw.print(" mNextAppTransitionPackage=");
10151 pw.print(mNextAppTransitionPackage);
10152 pw.print(", mNextAppTransitionEnter=0x");
10153 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10154 pw.print(", mNextAppTransitionExit=0x");
10155 pw.print(Integer.toHexString(mNextAppTransitionExit));
10156 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010157 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
10158 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010159 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
10160 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
10161 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
10162 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010163 if (mOpeningApps.size() > 0) {
10164 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10165 }
10166 if (mClosingApps.size() > 0) {
10167 pw.print(" mClosingApps="); pw.println(mClosingApps);
10168 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010169 if (mToTopApps.size() > 0) {
10170 pw.print(" mToTopApps="); pw.println(mToTopApps);
10171 }
10172 if (mToBottomApps.size() > 0) {
10173 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
10174 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010175 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
10176 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 }
10178 }
10179
Jeff Brown349703e2010-06-22 01:27:15 -070010180 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 public void monitor() {
10182 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050010183 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010184 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010185
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010186 /**
10187 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010188 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010189 */
10190 private static class DimAnimator {
10191 Surface mDimSurface;
10192 boolean mDimShown = false;
10193 float mDimCurrentAlpha;
10194 float mDimTargetAlpha;
10195 float mDimDeltaPerMs;
10196 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070010197
10198 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010199
10200 DimAnimator (SurfaceSession session) {
10201 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010202 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010203 + mDimSurface + ": CREATE");
10204 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010205 mDimSurface = new Surface(session, 0,
10206 "DimSurface",
10207 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010208 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010010209 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010210 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010211 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010212 }
10213 }
10214 }
10215
10216 /**
10217 * Show the dim surface.
10218 */
10219 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010220 if (!mDimShown) {
10221 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
10222 dw + "x" + dh + ")");
10223 mDimShown = true;
10224 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070010225 mLastDimWidth = dw;
10226 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010227 mDimSurface.setPosition(0, 0);
10228 mDimSurface.setSize(dw, dh);
10229 mDimSurface.show();
10230 } catch (RuntimeException e) {
10231 Slog.w(TAG, "Failure showing dim surface", e);
10232 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070010233 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
10234 mLastDimWidth = dw;
10235 mLastDimHeight = dh;
10236 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010237 }
10238 }
10239
10240 /**
10241 * Set's the dim surface's layer and update dim parameters that will be used in
10242 * {@link updateSurface} after all windows are examined.
10243 */
10244 void updateParameters(WindowState w, long currentTime) {
10245 mDimSurface.setLayer(w.mAnimLayer-1);
10246
10247 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010248 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010249 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010250 if (mDimTargetAlpha != target) {
10251 // If the desired dim level has changed, then
10252 // start an animation to it.
10253 mLastDimAnimTime = currentTime;
10254 long duration = (w.mAnimating && w.mAnimation != null)
10255 ? w.mAnimation.computeDurationHint()
10256 : DEFAULT_DIM_DURATION;
10257 if (target > mDimTargetAlpha) {
10258 // This is happening behind the activity UI,
10259 // so we can make it run a little longer to
10260 // give a stronger impression without disrupting
10261 // the user.
10262 duration *= DIM_DURATION_MULTIPLIER;
10263 }
10264 if (duration < 1) {
10265 // Don't divide by zero
10266 duration = 1;
10267 }
10268 mDimTargetAlpha = target;
10269 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
10270 }
10271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010272
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010273 /**
10274 * Updating the surface's alpha. Returns true if the animation continues, or returns
10275 * false when the animation is finished and the dim surface is hidden.
10276 */
10277 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
10278 if (!dimming) {
10279 if (mDimTargetAlpha != 0) {
10280 mLastDimAnimTime = currentTime;
10281 mDimTargetAlpha = 0;
10282 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
10283 }
10284 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010285
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010286 boolean animating = false;
10287 if (mLastDimAnimTime != 0) {
10288 mDimCurrentAlpha += mDimDeltaPerMs
10289 * (currentTime-mLastDimAnimTime);
10290 boolean more = true;
10291 if (displayFrozen) {
10292 // If the display is frozen, there is no reason to animate.
10293 more = false;
10294 } else if (mDimDeltaPerMs > 0) {
10295 if (mDimCurrentAlpha > mDimTargetAlpha) {
10296 more = false;
10297 }
10298 } else if (mDimDeltaPerMs < 0) {
10299 if (mDimCurrentAlpha < mDimTargetAlpha) {
10300 more = false;
10301 }
10302 } else {
10303 more = false;
10304 }
10305
10306 // Do we need to continue animating?
10307 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010308 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010309 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
10310 mLastDimAnimTime = currentTime;
10311 mDimSurface.setAlpha(mDimCurrentAlpha);
10312 animating = true;
10313 } else {
10314 mDimCurrentAlpha = mDimTargetAlpha;
10315 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010316 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010317 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
10318 mDimSurface.setAlpha(mDimCurrentAlpha);
10319 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010320 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010321 + ": HIDE");
10322 try {
10323 mDimSurface.hide();
10324 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010325 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010326 }
10327 mDimShown = false;
10328 }
10329 }
10330 }
10331 return animating;
10332 }
10333
10334 public void printTo(PrintWriter pw) {
10335 pw.print(" mDimShown="); pw.print(mDimShown);
10336 pw.print(" current="); pw.print(mDimCurrentAlpha);
10337 pw.print(" target="); pw.print(mDimTargetAlpha);
10338 pw.print(" delta="); pw.print(mDimDeltaPerMs);
10339 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
10340 }
10341 }
10342
10343 /**
10344 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
10345 * This is used for opening/closing transition for apps in compatible mode.
10346 */
10347 private static class FadeInOutAnimation extends Animation {
10348 int mWidth;
10349 boolean mFadeIn;
10350
10351 public FadeInOutAnimation(boolean fadeIn) {
10352 setInterpolator(new AccelerateInterpolator());
10353 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
10354 mFadeIn = fadeIn;
10355 }
10356
10357 @Override
10358 protected void applyTransformation(float interpolatedTime, Transformation t) {
10359 float x = interpolatedTime;
10360 if (!mFadeIn) {
10361 x = 1.0f - x; // reverse the interpolation for fade out
10362 }
10363 if (x < 0.5) {
10364 // move the window out of the screen.
10365 t.getMatrix().setTranslate(mWidth, 0);
10366 } else {
10367 t.getMatrix().setTranslate(0, 0);// show
10368 t.setAlpha((x - 0.5f) * 2);
10369 }
10370 }
10371
10372 @Override
10373 public void initialize(int width, int height, int parentWidth, int parentHeight) {
10374 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
10375 mWidth = width;
10376 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010377
10378 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070010379 public int getZAdjustment() {
10380 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010381 }
10382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010383}