blob: e13f0af5a66899b44d355cca3deedc86786b02a5 [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.KeyInputQueue.QueuedEvent;
52import com.android.server.am.BatteryStatsService;
53
54import android.Manifest;
55import android.app.ActivityManagerNative;
56import android.app.IActivityManager;
Jim Millerd6b57052010-06-07 17:52:42 -070057import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.Context;
59import android.content.pm.ActivityInfo;
60import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070061import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.res.Configuration;
63import android.graphics.Matrix;
64import android.graphics.PixelFormat;
65import android.graphics.Rect;
66import android.graphics.Region;
67import android.os.BatteryStats;
68import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070069import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.os.Debug;
71import android.os.Handler;
72import android.os.IBinder;
Michael Chan53071d62009-05-13 17:29:48 -070073import android.os.LatencyTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.LocalPowerManager;
75import android.os.Looper;
76import android.os.Message;
77import android.os.Parcel;
78import android.os.ParcelFileDescriptor;
79import android.os.Power;
80import android.os.PowerManager;
81import android.os.Process;
82import android.os.RemoteException;
83import android.os.ServiceManager;
84import android.os.SystemClock;
85import android.os.SystemProperties;
86import android.os.TokenWatcher;
87import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070088import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070090import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080091import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.util.SparseIntArray;
93import android.view.Display;
94import android.view.Gravity;
95import android.view.IApplicationToken;
96import android.view.IOnKeyguardExitResult;
97import android.view.IRotationWatcher;
98import android.view.IWindow;
99import android.view.IWindowManager;
100import android.view.IWindowSession;
101import android.view.KeyEvent;
102import android.view.MotionEvent;
103import android.view.RawInputEvent;
104import android.view.Surface;
105import android.view.SurfaceSession;
106import android.view.View;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700107import android.view.ViewConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.view.ViewTreeObserver;
109import android.view.WindowManager;
110import android.view.WindowManagerImpl;
111import android.view.WindowManagerPolicy;
112import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700113import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.animation.Animation;
115import android.view.animation.AnimationUtils;
116import android.view.animation.Transformation;
117
118import java.io.BufferedWriter;
119import java.io.File;
120import java.io.FileDescriptor;
121import java.io.IOException;
122import java.io.OutputStream;
123import java.io.OutputStreamWriter;
124import java.io.PrintWriter;
125import java.io.StringWriter;
126import java.net.Socket;
127import java.util.ArrayList;
128import java.util.HashMap;
129import java.util.HashSet;
130import java.util.Iterator;
131import java.util.List;
132
133/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700134public class WindowManagerService extends IWindowManager.Stub
135 implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 static final String TAG = "WindowManager";
137 static final boolean DEBUG = false;
138 static final boolean DEBUG_FOCUS = false;
139 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800140 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800141 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 static final boolean DEBUG_LAYERS = false;
143 static final boolean DEBUG_INPUT = false;
144 static final boolean DEBUG_INPUT_METHOD = false;
145 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700146 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700148 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final boolean DEBUG_APP_TRANSITIONS = false;
150 static final boolean DEBUG_STARTING_WINDOW = false;
151 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700152 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackbornce73c1e2010-04-12 23:11:38 -0700153 static final boolean DEBUG_FREEZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700155 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700156 static final boolean MEASURE_LATENCY = false;
157 static private LatencyTimer lt;
158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean PROFILE_ORIENTATION = false;
160 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700161 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 /** How long to wait for subsequent key repeats, in milliseconds */
164 static final int KEY_REPEAT_DELAY = 50;
165
166 /** How much to multiply the policy's type layer, to reserve room
167 * for multiple windows of the same type and Z-ordering adjustment
168 * with TYPE_LAYER_OFFSET. */
169 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
172 * or below others in the same layer. */
173 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 /** How much to increment the layer for each window, to reserve room
176 * for effect surfaces between them.
177 */
178 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 /** The maximum length we will accept for a loaded animation duration:
181 * this is 10 seconds.
182 */
183 static final int MAX_ANIMATION_DURATION = 10*1000;
184
185 /** Amount of time (in milliseconds) to animate the dim surface from one
186 * value to another, when no window animation is driving it.
187 */
188 static final int DEFAULT_DIM_DURATION = 200;
189
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700190 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
191 * compatible windows.
192 */
193 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 /** Adjustment to time to perform a dim, to make it more dramatic.
196 */
197 static final int DIM_DURATION_MULTIPLIER = 6;
Romain Guy06882f82009-06-10 13:36:04 -0700198
Dianne Hackborncfaef692009-06-15 14:24:44 -0700199 static final int INJECT_FAILED = 0;
200 static final int INJECT_SUCCEEDED = 1;
201 static final int INJECT_NO_PERMISSION = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 static final int UPDATE_FOCUS_NORMAL = 0;
204 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
205 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
206 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700207
Michael Chane96440f2009-05-06 10:27:36 -0700208 /** The minimum time between dispatching touch events. */
209 int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
210
211 // Last touch event time
212 long mLastTouchEventTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700213
Michael Chane96440f2009-05-06 10:27:36 -0700214 // Last touch event type
215 int mLastTouchEventType = OTHER_EVENT;
Romain Guy06882f82009-06-10 13:36:04 -0700216
Michael Chane96440f2009-05-06 10:27:36 -0700217 // Time to wait before calling useractivity again. This saves CPU usage
218 // when we get a flood of touch events.
219 static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
220
221 // Last time we call user activity
222 long mLastUserActivityCallTime = 0;
223
Romain Guy06882f82009-06-10 13:36:04 -0700224 // Last time we updated battery stats
Michael Chane96440f2009-05-06 10:27:36 -0700225 long mLastBatteryStatsCallTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700228 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229
230 /**
231 * Condition waited on by {@link #reenableKeyguard} to know the call to
232 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500233 * This is set to true only if mKeyguardTokenWatcher.acquired() has
234 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500236 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237
Mike Lockwood983ee092009-11-22 01:42:24 -0500238 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
239 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 public void acquired() {
241 mPolicy.enableKeyguard(false);
Mike Lockwood983ee092009-11-22 01:42:24 -0500242 mKeyguardDisabled = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 }
244 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700245 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500246 synchronized (mKeyguardTokenWatcher) {
247 mKeyguardDisabled = false;
248 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 }
250 }
251 };
252
253 final Context mContext;
254
255 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
260
261 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 /**
266 * All currently active sessions with clients.
267 */
268 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 /**
271 * Mapping from an IWindow IBinder to the server's Window object.
272 * This is also used as the lock for all of our state.
273 */
274 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
275
276 /**
277 * Mapping from a token IBinder to a WindowToken object.
278 */
279 final HashMap<IBinder, WindowToken> mTokenMap =
280 new HashMap<IBinder, WindowToken>();
281
282 /**
283 * The same tokens as mTokenMap, stored in a list for efficient iteration
284 * over them.
285 */
286 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 /**
289 * Window tokens that are in the process of exiting, but still
290 * on screen for animations.
291 */
292 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
293
294 /**
295 * Z-ordered (bottom-most first) list of all application tokens, for
296 * controlling the ordering of windows in different applications. This
297 * contains WindowToken objects.
298 */
299 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
300
301 /**
302 * Application tokens that are in the process of exiting, but still
303 * on screen for animations.
304 */
305 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
306
307 /**
308 * List of window tokens that have finished starting their application,
309 * and now need to have the policy remove their windows.
310 */
311 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
312
313 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700314 * This was the app token that was used to retrieve the last enter
315 * animation. It will be used for the next exit animation.
316 */
317 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800318
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700319 /**
320 * These were the layout params used to retrieve the last enter animation.
321 * They will be used for the next exit animation.
322 */
323 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800324
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700325 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 * Z-ordered (bottom-most first) list of all Window objects.
327 */
328 final ArrayList mWindows = new ArrayList();
329
330 /**
331 * Windows that are being resized. Used so we can tell the client about
332 * the resize after closing the transaction in which we resized the
333 * underlying surface.
334 */
335 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
336
337 /**
338 * Windows whose animations have ended and now must be removed.
339 */
340 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
341
342 /**
343 * Windows whose surface should be destroyed.
344 */
345 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
346
347 /**
348 * Windows that have lost input focus and are waiting for the new
349 * focus window to be displayed before they are told about this.
350 */
351 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
352
353 /**
354 * This is set when we have run out of memory, and will either be an empty
355 * list or contain windows that need to be force removed.
356 */
357 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700362 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 Surface mBlurSurface;
364 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 final float[] mTmpFloats = new float[9];
369
370 boolean mSafeMode;
371 boolean mDisplayEnabled = false;
372 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700373 int mInitialDisplayWidth = 0;
374 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 int mRotation = 0;
376 int mRequestedRotation = 0;
377 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700378 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 ArrayList<IRotationWatcher> mRotationWatchers
380 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 boolean mLayoutNeeded = true;
383 boolean mAnimationPending = false;
384 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800385 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 boolean mWindowsFreezingScreen = false;
387 long mFreezeGcPending = 0;
388 int mAppsFreezingScreen = 0;
389
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800390 int mLayoutSeq = 0;
391
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800392 // State while inside of layoutAndPlaceSurfacesLocked().
393 boolean mFocusMayChange;
394
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800395 Configuration mCurConfiguration = new Configuration();
396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 // This is held as long as we have the screen frozen, to give us time to
398 // perform a rotation animation when turning off shows the lock screen which
399 // changes the orientation.
400 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 // State management of app transitions. When we are preparing for a
403 // transition, mNextAppTransition will be the kind of transition to
404 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
405 // mOpeningApps and mClosingApps are the lists of tokens that will be
406 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700407 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700408 String mNextAppTransitionPackage;
409 int mNextAppTransitionEnter;
410 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700412 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 boolean mAppTransitionTimeout = false;
414 boolean mStartingIconInTransition = false;
415 boolean mSkipAppTransitionAnimation = false;
416 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
417 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700418 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
419 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 //flag to detect fat touch events
422 boolean mFatTouch = false;
423 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 H mH = new H();
426
427 WindowState mCurrentFocus = null;
428 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 // This just indicates the window the input method is on top of, not
431 // necessarily the window its input is going to.
432 WindowState mInputMethodTarget = null;
433 WindowState mUpcomingInputMethodTarget = null;
434 boolean mInputMethodTargetWaitingAnim;
435 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 WindowState mInputMethodWindow = null;
438 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
439
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700440 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800441
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700442 // If non-null, this is the currently visible window that is associated
443 // with the wallpaper.
444 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700445 // If non-null, we are in the middle of animating from one wallpaper target
446 // to another, and this is the lower one in Z-order.
447 WindowState mLowerWallpaperTarget = null;
448 // If non-null, we are in the middle of animating from one wallpaper target
449 // to another, and this is the higher one in Z-order.
450 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700451 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700452 float mLastWallpaperX = -1;
453 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800454 float mLastWallpaperXStep = -1;
455 float mLastWallpaperYStep = -1;
Dianne Hackborn6adba242009-11-10 11:10:09 -0800456 boolean mSendingPointersToWallpaper = false;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700457 // This is set when we are waiting for a wallpaper to tell us it is done
458 // changing its scroll position.
459 WindowState mWaitingOnWallpaper;
460 // The last time we had a timeout when waiting for a wallpaper.
461 long mLastWallpaperTimeoutTime;
462 // We give a wallpaper up to 150ms to finish scrolling.
463 static final long WALLPAPER_TIMEOUT = 150;
464 // Time we wait after a timeout before trying to wait again.
465 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 AppWindowToken mFocusedApp = null;
468
469 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 float mWindowAnimationScale = 1.0f;
472 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 final KeyWaiter mKeyWaiter = new KeyWaiter();
475 final KeyQ mQueue;
476 final InputDispatcherThread mInputThread;
477
478 // Who is holding the screen on.
479 Session mHoldingScreenOn;
Romain Guy06882f82009-06-10 13:36:04 -0700480
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700481 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 /**
484 * Whether the UI is currently running in touch mode (not showing
485 * navigational focus because the user is directly pressing the screen).
486 */
487 boolean mInTouchMode = false;
488
489 private ViewServer mViewServer;
490
491 final Rect mTempRect = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -0700492
Dianne Hackbornc485a602009-03-24 22:39:49 -0700493 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700494 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700495
496 // The frame use to limit the size of the app running in compatibility mode.
497 Rect mCompatibleScreenFrame = new Rect();
498 // The surface used to fill the outer rim of the app running in compatibility mode.
499 Surface mBackgroundFillerSurface = null;
500 boolean mBackgroundFillerShown = false;
501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 public static WindowManagerService main(Context context,
503 PowerManagerService pm, boolean haveInputMethods) {
504 WMThread thr = new WMThread(context, pm, haveInputMethods);
505 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 synchronized (thr) {
508 while (thr.mService == null) {
509 try {
510 thr.wait();
511 } catch (InterruptedException e) {
512 }
513 }
514 }
Romain Guy06882f82009-06-10 13:36:04 -0700515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 return thr.mService;
517 }
Romain Guy06882f82009-06-10 13:36:04 -0700518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 static class WMThread extends Thread {
520 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 private final Context mContext;
523 private final PowerManagerService mPM;
524 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 public WMThread(Context context, PowerManagerService pm,
527 boolean haveInputMethods) {
528 super("WindowManager");
529 mContext = context;
530 mPM = pm;
531 mHaveInputMethods = haveInputMethods;
532 }
Romain Guy06882f82009-06-10 13:36:04 -0700533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 public void run() {
535 Looper.prepare();
536 WindowManagerService s = new WindowManagerService(mContext, mPM,
537 mHaveInputMethods);
538 android.os.Process.setThreadPriority(
539 android.os.Process.THREAD_PRIORITY_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -0700540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 synchronized (this) {
542 mService = s;
543 notifyAll();
544 }
Romain Guy06882f82009-06-10 13:36:04 -0700545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 Looper.loop();
547 }
548 }
549
550 static class PolicyThread extends Thread {
551 private final WindowManagerPolicy mPolicy;
552 private final WindowManagerService mService;
553 private final Context mContext;
554 private final PowerManagerService mPM;
555 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 public PolicyThread(WindowManagerPolicy policy,
558 WindowManagerService service, Context context,
559 PowerManagerService pm) {
560 super("WindowManagerPolicy");
561 mPolicy = policy;
562 mService = service;
563 mContext = context;
564 mPM = pm;
565 }
Romain Guy06882f82009-06-10 13:36:04 -0700566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 public void run() {
568 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800569 WindowManagerPolicyThread.set(this, Looper.myLooper());
570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800572 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 android.os.Process.setThreadPriority(
574 android.os.Process.THREAD_PRIORITY_FOREGROUND);
575 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 synchronized (this) {
578 mRunning = true;
579 notifyAll();
580 }
Romain Guy06882f82009-06-10 13:36:04 -0700581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 Looper.loop();
583 }
584 }
585
586 private WindowManagerService(Context context, PowerManagerService pm,
587 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700588 if (MEASURE_LATENCY) {
589 lt = new LatencyTimer(100, 1000);
590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 mContext = context;
593 mHaveInputMethods = haveInputMethods;
594 mLimitedAlphaCompositing = context.getResources().getBoolean(
595 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 mPowerManager = pm;
598 mPowerManager.setPolicy(mPolicy);
599 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
600 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
601 "SCREEN_FROZEN");
602 mScreenFrozenLock.setReferenceCounted(false);
603
604 mActivityManager = ActivityManagerNative.getDefault();
605 mBatteryStats = BatteryStatsService.getService();
606
607 // Get persisted window scale setting
608 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
609 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
610 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
611 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700612
Michael Chan9f028e62009-08-04 17:37:46 -0700613 int max_events_per_sec = 35;
614 try {
615 max_events_per_sec = Integer.parseInt(SystemProperties
616 .get("windowsmgr.max_events_per_sec"));
617 if (max_events_per_sec < 1) {
618 max_events_per_sec = 35;
619 }
620 } catch (NumberFormatException e) {
621 }
622 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 mQueue = new KeyQ();
625
626 mInputThread = new InputDispatcherThread();
Romain Guy06882f82009-06-10 13:36:04 -0700627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
629 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 synchronized (thr) {
632 while (!thr.mRunning) {
633 try {
634 thr.wait();
635 } catch (InterruptedException e) {
636 }
637 }
638 }
Romain Guy06882f82009-06-10 13:36:04 -0700639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 mInputThread.start();
Romain Guy06882f82009-06-10 13:36:04 -0700641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642 // Add ourself to the Watchdog monitors.
643 Watchdog.getInstance().addMonitor(this);
644 }
645
646 @Override
647 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
648 throws RemoteException {
649 try {
650 return super.onTransact(code, data, reply, flags);
651 } catch (RuntimeException e) {
652 // The window manager only throws security exceptions, so let's
653 // log all others.
654 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800655 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 }
657 throw e;
658 }
659 }
660
661 private void placeWindowAfter(Object pos, WindowState window) {
662 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800663 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 TAG, "Adding window " + window + " at "
665 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
666 mWindows.add(i+1, window);
667 }
668
669 private void placeWindowBefore(Object pos, WindowState window) {
670 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800671 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 TAG, "Adding window " + window + " at "
673 + i + " of " + mWindows.size() + " (before " + pos + ")");
674 mWindows.add(i, window);
675 }
676
677 //This method finds out the index of a window that has the same app token as
678 //win. used for z ordering the windows in mWindows
679 private int findIdxBasedOnAppTokens(WindowState win) {
680 //use a local variable to cache mWindows
681 ArrayList localmWindows = mWindows;
682 int jmax = localmWindows.size();
683 if(jmax == 0) {
684 return -1;
685 }
686 for(int j = (jmax-1); j >= 0; j--) {
687 WindowState wentry = (WindowState)localmWindows.get(j);
688 if(wentry.mAppToken == win.mAppToken) {
689 return j;
690 }
691 }
692 return -1;
693 }
Romain Guy06882f82009-06-10 13:36:04 -0700694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
696 final IWindow client = win.mClient;
697 final WindowToken token = win.mToken;
698 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 final int N = localmWindows.size();
701 final WindowState attached = win.mAttachedWindow;
702 int i;
703 if (attached == null) {
704 int tokenWindowsPos = token.windows.size();
705 if (token.appWindowToken != null) {
706 int index = tokenWindowsPos-1;
707 if (index >= 0) {
708 // If this application has existing windows, we
709 // simply place the new window on top of them... but
710 // keep the starting window on top.
711 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
712 // Base windows go behind everything else.
713 placeWindowBefore(token.windows.get(0), win);
714 tokenWindowsPos = 0;
715 } else {
716 AppWindowToken atoken = win.mAppToken;
717 if (atoken != null &&
718 token.windows.get(index) == atoken.startingWindow) {
719 placeWindowBefore(token.windows.get(index), win);
720 tokenWindowsPos--;
721 } else {
722 int newIdx = findIdxBasedOnAppTokens(win);
723 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700724 //there is a window above this one associated with the same
725 //apptoken note that the window could be a floating window
726 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800728 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700729 TAG, "Adding window " + win + " at "
730 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 localmWindows.add(newIdx+1, win);
Romain Guy06882f82009-06-10 13:36:04 -0700732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 }
734 }
735 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800736 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 TAG, "Figuring out where to add app window "
738 + client.asBinder() + " (token=" + token + ")");
739 // Figure out where the window should go, based on the
740 // order of applications.
741 final int NA = mAppTokens.size();
742 Object pos = null;
743 for (i=NA-1; i>=0; i--) {
744 AppWindowToken t = mAppTokens.get(i);
745 if (t == token) {
746 i--;
747 break;
748 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800749
Dianne Hackborna8f60182009-09-01 19:01:50 -0700750 // We haven't reached the token yet; if this token
751 // is not going to the bottom and has windows, we can
752 // use it as an anchor for when we do reach the token.
753 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 pos = t.windows.get(0);
755 }
756 }
757 // We now know the index into the apps. If we found
758 // an app window above, that gives us the position; else
759 // we need to look some more.
760 if (pos != null) {
761 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700762 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 mTokenMap.get(((WindowState)pos).mClient.asBinder());
764 if (atoken != null) {
765 final int NC = atoken.windows.size();
766 if (NC > 0) {
767 WindowState bottom = atoken.windows.get(0);
768 if (bottom.mSubLayer < 0) {
769 pos = bottom;
770 }
771 }
772 }
773 placeWindowBefore(pos, win);
774 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700775 // Continue looking down until we find the first
776 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 while (i >= 0) {
778 AppWindowToken t = mAppTokens.get(i);
779 final int NW = t.windows.size();
780 if (NW > 0) {
781 pos = t.windows.get(NW-1);
782 break;
783 }
784 i--;
785 }
786 if (pos != null) {
787 // Move in front of any windows attached to this
788 // one.
789 WindowToken atoken =
790 mTokenMap.get(((WindowState)pos).mClient.asBinder());
791 if (atoken != null) {
792 final int NC = atoken.windows.size();
793 if (NC > 0) {
794 WindowState top = atoken.windows.get(NC-1);
795 if (top.mSubLayer >= 0) {
796 pos = top;
797 }
798 }
799 }
800 placeWindowAfter(pos, win);
801 } else {
802 // Just search for the start of this layer.
803 final int myLayer = win.mBaseLayer;
804 for (i=0; i<N; i++) {
805 WindowState w = (WindowState)localmWindows.get(i);
806 if (w.mBaseLayer > myLayer) {
807 break;
808 }
809 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800810 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700811 TAG, "Adding window " + win + " at "
812 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 localmWindows.add(i, win);
814 }
815 }
816 }
817 } else {
818 // Figure out where window should go, based on layer.
819 final int myLayer = win.mBaseLayer;
820 for (i=N-1; i>=0; i--) {
821 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
822 i++;
823 break;
824 }
825 }
826 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800827 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700828 TAG, "Adding window " + win + " at "
829 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 localmWindows.add(i, win);
831 }
832 if (addToToken) {
833 token.windows.add(tokenWindowsPos, win);
834 }
835
836 } else {
837 // Figure out this window's ordering relative to the window
838 // it is attached to.
839 final int NA = token.windows.size();
840 final int sublayer = win.mSubLayer;
841 int largestSublayer = Integer.MIN_VALUE;
842 WindowState windowWithLargestSublayer = null;
843 for (i=0; i<NA; i++) {
844 WindowState w = token.windows.get(i);
845 final int wSublayer = w.mSubLayer;
846 if (wSublayer >= largestSublayer) {
847 largestSublayer = wSublayer;
848 windowWithLargestSublayer = w;
849 }
850 if (sublayer < 0) {
851 // For negative sublayers, we go below all windows
852 // in the same sublayer.
853 if (wSublayer >= sublayer) {
854 if (addToToken) {
855 token.windows.add(i, win);
856 }
857 placeWindowBefore(
858 wSublayer >= 0 ? attached : w, win);
859 break;
860 }
861 } else {
862 // For positive sublayers, we go above all windows
863 // in the same sublayer.
864 if (wSublayer > sublayer) {
865 if (addToToken) {
866 token.windows.add(i, win);
867 }
868 placeWindowBefore(w, win);
869 break;
870 }
871 }
872 }
873 if (i >= NA) {
874 if (addToToken) {
875 token.windows.add(win);
876 }
877 if (sublayer < 0) {
878 placeWindowBefore(attached, win);
879 } else {
880 placeWindowAfter(largestSublayer >= 0
881 ? windowWithLargestSublayer
882 : attached,
883 win);
884 }
885 }
886 }
Romain Guy06882f82009-06-10 13:36:04 -0700887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 if (win.mAppToken != null && addToToken) {
889 win.mAppToken.allAppWindows.add(win);
890 }
891 }
Romain Guy06882f82009-06-10 13:36:04 -0700892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 static boolean canBeImeTarget(WindowState w) {
894 final int fl = w.mAttrs.flags
895 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
896 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
897 return w.isVisibleOrAdding();
898 }
899 return false;
900 }
Romain Guy06882f82009-06-10 13:36:04 -0700901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
903 final ArrayList localmWindows = mWindows;
904 final int N = localmWindows.size();
905 WindowState w = null;
906 int i = N;
907 while (i > 0) {
908 i--;
909 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700910
Joe Onorato8a9b2202010-02-26 18:56:32 -0800911 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 // + Integer.toHexString(w.mAttrs.flags));
913 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800914 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 // Yet more tricksyness! If this window is a "starting"
917 // window, we do actually want to be on top of it, but
918 // it is not -really- where input will go. So if the caller
919 // is not actually looking to move the IME, look down below
920 // for a real window to target...
921 if (!willMove
922 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
923 && i > 0) {
924 WindowState wb = (WindowState)localmWindows.get(i-1);
925 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
926 i--;
927 w = wb;
928 }
929 }
930 break;
931 }
932 }
Romain Guy06882f82009-06-10 13:36:04 -0700933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700935
Joe Onorato8a9b2202010-02-26 18:56:32 -0800936 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 if (willMove && w != null) {
940 final WindowState curTarget = mInputMethodTarget;
941 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 // Now some fun for dealing with window animations that
944 // modify the Z order. We need to look at all windows below
945 // the current target that are in this app, finding the highest
946 // visible one in layering.
947 AppWindowToken token = curTarget.mAppToken;
948 WindowState highestTarget = null;
949 int highestPos = 0;
950 if (token.animating || token.animation != null) {
951 int pos = 0;
952 pos = localmWindows.indexOf(curTarget);
953 while (pos >= 0) {
954 WindowState win = (WindowState)localmWindows.get(pos);
955 if (win.mAppToken != token) {
956 break;
957 }
958 if (!win.mRemoved) {
959 if (highestTarget == null || win.mAnimLayer >
960 highestTarget.mAnimLayer) {
961 highestTarget = win;
962 highestPos = pos;
963 }
964 }
965 pos--;
966 }
967 }
Romain Guy06882f82009-06-10 13:36:04 -0700968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800970 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 + mNextAppTransition + " " + highestTarget
972 + " animating=" + highestTarget.isAnimating()
973 + " layer=" + highestTarget.mAnimLayer
974 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -0700975
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700976 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 // If we are currently setting up for an animation,
978 // hold everything until we can find out what will happen.
979 mInputMethodTargetWaitingAnim = true;
980 mInputMethodTarget = highestTarget;
981 return highestPos + 1;
982 } else if (highestTarget.isAnimating() &&
983 highestTarget.mAnimLayer > w.mAnimLayer) {
984 // If the window we are currently targeting is involved
985 // with an animation, and it is on top of the next target
986 // we will be over, then hold off on moving until
987 // that is done.
988 mInputMethodTarget = highestTarget;
989 return highestPos + 1;
990 }
991 }
992 }
993 }
Romain Guy06882f82009-06-10 13:36:04 -0700994
Joe Onorato8a9b2202010-02-26 18:56:32 -0800995 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 if (w != null) {
997 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -0800998 if (DEBUG_INPUT_METHOD) {
999 RuntimeException e = null;
1000 if (!HIDE_STACK_CRAWLS) {
1001 e = new RuntimeException();
1002 e.fillInStackTrace();
1003 }
1004 Slog.w(TAG, "Moving IM target from "
1005 + mInputMethodTarget + " to " + w, e);
1006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 mInputMethodTarget = w;
1008 if (w.mAppToken != null) {
1009 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1010 } else {
1011 setInputMethodAnimLayerAdjustment(0);
1012 }
1013 }
1014 return i+1;
1015 }
1016 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001017 if (DEBUG_INPUT_METHOD) {
1018 RuntimeException e = null;
1019 if (!HIDE_STACK_CRAWLS) {
1020 e = new RuntimeException();
1021 e.fillInStackTrace();
1022 }
1023 Slog.w(TAG, "Moving IM target from "
1024 + mInputMethodTarget + " to null", e);
1025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026 mInputMethodTarget = null;
1027 setInputMethodAnimLayerAdjustment(0);
1028 }
1029 return -1;
1030 }
Romain Guy06882f82009-06-10 13:36:04 -07001031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 void addInputMethodWindowToListLocked(WindowState win) {
1033 int pos = findDesiredInputMethodWindowIndexLocked(true);
1034 if (pos >= 0) {
1035 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001036 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001037 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038 mWindows.add(pos, win);
1039 moveInputMethodDialogsLocked(pos+1);
1040 return;
1041 }
1042 win.mTargetAppToken = null;
1043 addWindowToListInOrderLocked(win, true);
1044 moveInputMethodDialogsLocked(pos);
1045 }
Romain Guy06882f82009-06-10 13:36:04 -07001046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001048 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 mInputMethodAnimLayerAdjustment = adj;
1050 WindowState imw = mInputMethodWindow;
1051 if (imw != null) {
1052 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001053 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 + " anim layer: " + imw.mAnimLayer);
1055 int wi = imw.mChildWindows.size();
1056 while (wi > 0) {
1057 wi--;
1058 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1059 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001060 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 + " anim layer: " + cw.mAnimLayer);
1062 }
1063 }
1064 int di = mInputMethodDialogs.size();
1065 while (di > 0) {
1066 di --;
1067 imw = mInputMethodDialogs.get(di);
1068 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001069 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 + " anim layer: " + imw.mAnimLayer);
1071 }
1072 }
Romain Guy06882f82009-06-10 13:36:04 -07001073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1075 int wpos = mWindows.indexOf(win);
1076 if (wpos >= 0) {
1077 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001078 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 mWindows.remove(wpos);
1080 int NC = win.mChildWindows.size();
1081 while (NC > 0) {
1082 NC--;
1083 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1084 int cpos = mWindows.indexOf(cw);
1085 if (cpos >= 0) {
1086 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001087 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001088 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 mWindows.remove(cpos);
1090 }
1091 }
1092 }
1093 return interestingPos;
1094 }
Romain Guy06882f82009-06-10 13:36:04 -07001095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 private void reAddWindowToListInOrderLocked(WindowState win) {
1097 addWindowToListInOrderLocked(win, false);
1098 // This is a hack to get all of the child windows added as well
1099 // at the right position. Child windows should be rare and
1100 // this case should be rare, so it shouldn't be that big a deal.
1101 int wpos = mWindows.indexOf(win);
1102 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001103 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001104 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 mWindows.remove(wpos);
1106 reAddWindowLocked(wpos, win);
1107 }
1108 }
Romain Guy06882f82009-06-10 13:36:04 -07001109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 void logWindowList(String prefix) {
1111 int N = mWindows.size();
1112 while (N > 0) {
1113 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001114 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 }
1116 }
Romain Guy06882f82009-06-10 13:36:04 -07001117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 void moveInputMethodDialogsLocked(int pos) {
1119 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001122 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 for (int i=0; i<N; i++) {
1124 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1125 }
1126 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001127 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 logWindowList(" ");
1129 }
Romain Guy06882f82009-06-10 13:36:04 -07001130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 if (pos >= 0) {
1132 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1133 if (pos < mWindows.size()) {
1134 WindowState wp = (WindowState)mWindows.get(pos);
1135 if (wp == mInputMethodWindow) {
1136 pos++;
1137 }
1138 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001139 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 for (int i=0; i<N; i++) {
1141 WindowState win = dialogs.get(i);
1142 win.mTargetAppToken = targetAppToken;
1143 pos = reAddWindowLocked(pos, win);
1144 }
1145 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001146 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 logWindowList(" ");
1148 }
1149 return;
1150 }
1151 for (int i=0; i<N; i++) {
1152 WindowState win = dialogs.get(i);
1153 win.mTargetAppToken = null;
1154 reAddWindowToListInOrderLocked(win);
1155 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001156 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 logWindowList(" ");
1158 }
1159 }
1160 }
Romain Guy06882f82009-06-10 13:36:04 -07001161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1163 final WindowState imWin = mInputMethodWindow;
1164 final int DN = mInputMethodDialogs.size();
1165 if (imWin == null && DN == 0) {
1166 return false;
1167 }
Romain Guy06882f82009-06-10 13:36:04 -07001168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1170 if (imPos >= 0) {
1171 // In this case, the input method windows are to be placed
1172 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 // First check to see if the input method windows are already
1175 // located here, and contiguous.
1176 final int N = mWindows.size();
1177 WindowState firstImWin = imPos < N
1178 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 // Figure out the actual input method window that should be
1181 // at the bottom of their stack.
1182 WindowState baseImWin = imWin != null
1183 ? imWin : mInputMethodDialogs.get(0);
1184 if (baseImWin.mChildWindows.size() > 0) {
1185 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1186 if (cw.mSubLayer < 0) baseImWin = cw;
1187 }
Romain Guy06882f82009-06-10 13:36:04 -07001188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 if (firstImWin == baseImWin) {
1190 // The windows haven't moved... but are they still contiguous?
1191 // First find the top IM window.
1192 int pos = imPos+1;
1193 while (pos < N) {
1194 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1195 break;
1196 }
1197 pos++;
1198 }
1199 pos++;
1200 // Now there should be no more input method windows above.
1201 while (pos < N) {
1202 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1203 break;
1204 }
1205 pos++;
1206 }
1207 if (pos >= N) {
1208 // All is good!
1209 return false;
1210 }
1211 }
Romain Guy06882f82009-06-10 13:36:04 -07001212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 if (imWin != null) {
1214 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001215 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 logWindowList(" ");
1217 }
1218 imPos = tmpRemoveWindowLocked(imPos, imWin);
1219 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001220 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 logWindowList(" ");
1222 }
1223 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1224 reAddWindowLocked(imPos, imWin);
1225 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001226 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 logWindowList(" ");
1228 }
1229 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1230 } else {
1231 moveInputMethodDialogsLocked(imPos);
1232 }
Romain Guy06882f82009-06-10 13:36:04 -07001233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 } else {
1235 // In this case, the input method windows go in a fixed layer,
1236 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001239 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 tmpRemoveWindowLocked(0, imWin);
1241 imWin.mTargetAppToken = null;
1242 reAddWindowToListInOrderLocked(imWin);
1243 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001244 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 logWindowList(" ");
1246 }
1247 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1248 } else {
1249 moveInputMethodDialogsLocked(-1);;
1250 }
Romain Guy06882f82009-06-10 13:36:04 -07001251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 }
Romain Guy06882f82009-06-10 13:36:04 -07001253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 if (needAssignLayers) {
1255 assignLayersLocked();
1256 }
Romain Guy06882f82009-06-10 13:36:04 -07001257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 return true;
1259 }
Romain Guy06882f82009-06-10 13:36:04 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 void adjustInputMethodDialogsLocked() {
1262 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1263 }
Romain Guy06882f82009-06-10 13:36:04 -07001264
Dianne Hackborn25994b42009-09-04 14:21:19 -07001265 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001266 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001267 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1268 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1269 ? wallpaperTarget.mAppToken.animation : null)
1270 + " upper=" + mUpperWallpaperTarget
1271 + " lower=" + mLowerWallpaperTarget);
1272 return (wallpaperTarget != null
1273 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1274 && wallpaperTarget.mAppToken.animation != null)))
1275 || mUpperWallpaperTarget != null
1276 || mLowerWallpaperTarget != null;
1277 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001278
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001279 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1280 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001281
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001282 int adjustWallpaperWindowsLocked() {
1283 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001284
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001285 final int dw = mDisplay.getWidth();
1286 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001287
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001288 // First find top-most window that has asked to be on top of the
1289 // wallpaper; all wallpapers go behind it.
1290 final ArrayList localmWindows = mWindows;
1291 int N = localmWindows.size();
1292 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001293 WindowState foundW = null;
1294 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001295 WindowState topCurW = null;
1296 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001297 int i = N;
1298 while (i > 0) {
1299 i--;
1300 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001301 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1302 if (topCurW == null) {
1303 topCurW = w;
1304 topCurI = i;
1305 }
1306 continue;
1307 }
1308 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001309 if (w.mAppToken != null) {
1310 // If this window's app token is hidden and not animating,
1311 // it is of no interest to us.
1312 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001313 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001314 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001315 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001316 continue;
1317 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001318 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001319 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001320 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1321 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001322 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001323 && (mWallpaperTarget == w
1324 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001325 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001326 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001327 foundW = w;
1328 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001329 if (w == mWallpaperTarget && ((w.mAppToken != null
1330 && w.mAppToken.animation != null)
1331 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001332 // The current wallpaper target is animating, so we'll
1333 // look behind it for another possible target and figure
1334 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001335 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001336 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001337 continue;
1338 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001339 break;
1340 }
1341 }
1342
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001343 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001344 // If we are currently waiting for an app transition, and either
1345 // the current target or the next target are involved with it,
1346 // then hold off on doing anything with the wallpaper.
1347 // Note that we are checking here for just whether the target
1348 // is part of an app token... which is potentially overly aggressive
1349 // (the app token may not be involved in the transition), but good
1350 // enough (we'll just wait until whatever transition is pending
1351 // executes).
1352 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001354 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001355 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001356 }
1357 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001358 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001359 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001360 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001361 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001362 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001363
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001364 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001365 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001366 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001367 + " oldTarget: " + mWallpaperTarget);
1368 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001369
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001370 mLowerWallpaperTarget = null;
1371 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001372
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001373 WindowState oldW = mWallpaperTarget;
1374 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001375
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001376 // Now what is happening... if the current and new targets are
1377 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001378 if (foundW != null && oldW != null) {
1379 boolean oldAnim = oldW.mAnimation != null
1380 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1381 boolean foundAnim = foundW.mAnimation != null
1382 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001383 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001384 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001385 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001386 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001387 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001388 int oldI = localmWindows.indexOf(oldW);
1389 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001390 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001391 }
1392 if (oldI >= 0) {
1393 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001394 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001395 + "=" + oldW + "; new#" + foundI
1396 + "=" + foundW);
1397 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001398
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001399 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001400 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001401 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001402 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001403 }
1404 mWallpaperTarget = oldW;
1405 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001406
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001407 // Now set the upper and lower wallpaper targets
1408 // correctly, and make sure that we are positioning
1409 // the wallpaper below the lower.
1410 if (foundI > oldI) {
1411 // The new target is on top of the old one.
1412 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001413 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001414 }
1415 mUpperWallpaperTarget = foundW;
1416 mLowerWallpaperTarget = oldW;
1417 foundW = oldW;
1418 foundI = oldI;
1419 } else {
1420 // The new target is below the old one.
1421 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001423 }
1424 mUpperWallpaperTarget = oldW;
1425 mLowerWallpaperTarget = foundW;
1426 }
1427 }
1428 }
1429 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001430
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001431 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001432 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001433 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1434 || (mLowerWallpaperTarget.mAppToken != null
1435 && mLowerWallpaperTarget.mAppToken.animation != null);
1436 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1437 || (mUpperWallpaperTarget.mAppToken != null
1438 && mUpperWallpaperTarget.mAppToken.animation != null);
1439 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001440 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001441 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001442 }
1443 mLowerWallpaperTarget = null;
1444 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001445 }
1446 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001447
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001448 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001449 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001450 // The window is visible to the compositor... but is it visible
1451 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001452 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001453 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001454
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001455 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001456 // its layer adjustment. Only do this if we are not transfering
1457 // between two wallpaper targets.
1458 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001459 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001460 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001461
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001462 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1463 * TYPE_LAYER_MULTIPLIER
1464 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001465
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001466 // Now w is the window we are supposed to be behind... but we
1467 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001468 // AND any starting window associated with it, AND below the
1469 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001470 while (foundI > 0) {
1471 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001472 if (wb.mBaseLayer < maxLayer &&
1473 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001474 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001475 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001476 // This window is not related to the previous one in any
1477 // interesting way, so stop here.
1478 break;
1479 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001480 foundW = wb;
1481 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001482 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001483 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001485 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001486
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001487 if (foundW == null && topCurW != null) {
1488 // There is no wallpaper target, so it goes at the bottom.
1489 // We will assume it is the same place as last time, if known.
1490 foundW = topCurW;
1491 foundI = topCurI+1;
1492 } else {
1493 // Okay i is the position immediately above the wallpaper. Look at
1494 // what is below it for later.
1495 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1496 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001497
Dianne Hackborn284ac932009-08-28 10:34:25 -07001498 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001499 if (mWallpaperTarget.mWallpaperX >= 0) {
1500 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001501 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001502 }
1503 if (mWallpaperTarget.mWallpaperY >= 0) {
1504 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001505 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001506 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001507 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001508
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001509 // Start stepping backwards from here, ensuring that our wallpaper windows
1510 // are correctly placed.
1511 int curTokenIndex = mWallpaperTokens.size();
1512 while (curTokenIndex > 0) {
1513 curTokenIndex--;
1514 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001515 if (token.hidden == visible) {
1516 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1517 token.hidden = !visible;
1518 // Need to do a layout to ensure the wallpaper now has the
1519 // correct size.
1520 mLayoutNeeded = true;
1521 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001522
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001523 int curWallpaperIndex = token.windows.size();
1524 while (curWallpaperIndex > 0) {
1525 curWallpaperIndex--;
1526 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001527
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001528 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001529 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001530 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001531
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001532 // First, make sure the client has the current visibility
1533 // state.
1534 if (wallpaper.mWallpaperVisible != visible) {
1535 wallpaper.mWallpaperVisible = visible;
1536 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001537 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001538 "Setting visibility of wallpaper " + wallpaper
1539 + ": " + visible);
1540 wallpaper.mClient.dispatchAppVisibility(visible);
1541 } catch (RemoteException e) {
1542 }
1543 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001544
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001545 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001546 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001547 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001548
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001549 // First, if this window is at the current index, then all
1550 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001551 if (wallpaper == foundW) {
1552 foundI--;
1553 foundW = foundI > 0
1554 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001555 continue;
1556 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001557
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001558 // The window didn't match... the current wallpaper window,
1559 // wherever it is, is in the wrong place, so make sure it is
1560 // not in the list.
1561 int oldIndex = localmWindows.indexOf(wallpaper);
1562 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001563 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001564 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001565 localmWindows.remove(oldIndex);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001566 if (oldIndex < foundI) {
1567 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001568 }
1569 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001571 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001572 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001573 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001574 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001575
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001576 localmWindows.add(foundI, wallpaper);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001577 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001578 }
1579 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001580
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001581 return changed;
1582 }
1583
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001584 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001586 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001587 mWallpaperAnimLayerAdjustment = adj;
1588 int curTokenIndex = mWallpaperTokens.size();
1589 while (curTokenIndex > 0) {
1590 curTokenIndex--;
1591 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1592 int curWallpaperIndex = token.windows.size();
1593 while (curWallpaperIndex > 0) {
1594 curWallpaperIndex--;
1595 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1596 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001597 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001598 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001599 }
1600 }
1601 }
1602
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001603 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1604 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001605 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001606 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001607 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001608 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001609 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1610 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1611 changed = wallpaperWin.mXOffset != offset;
1612 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001613 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001614 + wallpaperWin + " x: " + offset);
1615 wallpaperWin.mXOffset = offset;
1616 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001617 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001618 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001619 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001620 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001621 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001622
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001623 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001624 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001625 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1626 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1627 if (wallpaperWin.mYOffset != offset) {
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 + " y: " + offset);
1630 changed = true;
1631 wallpaperWin.mYOffset = offset;
1632 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001633 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001634 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001635 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001636 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001637 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001638
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001639 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001640 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001642 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1643 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001644 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001645 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001646 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001647 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001648 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1649 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001650 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001651 if (mWaitingOnWallpaper != null) {
1652 long start = SystemClock.uptimeMillis();
1653 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1654 < start) {
1655 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001656 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001657 "Waiting for offset complete...");
1658 mWindowMap.wait(WALLPAPER_TIMEOUT);
1659 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001660 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001661 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001662 if ((start+WALLPAPER_TIMEOUT)
1663 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001664 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001665 + wallpaperWin);
1666 mLastWallpaperTimeoutTime = start;
1667 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001668 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001669 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001670 }
1671 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001672 } catch (RemoteException e) {
1673 }
1674 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001675
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001676 return changed;
1677 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001678
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001679 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001680 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001681 if (mWaitingOnWallpaper != null &&
1682 mWaitingOnWallpaper.mClient.asBinder() == window) {
1683 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001684 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001685 }
1686 }
1687 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001688
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001689 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001690 final int dw = mDisplay.getWidth();
1691 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001692
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001693 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001694
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001695 WindowState target = mWallpaperTarget;
1696 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001697 if (target.mWallpaperX >= 0) {
1698 mLastWallpaperX = target.mWallpaperX;
1699 } else if (changingTarget.mWallpaperX >= 0) {
1700 mLastWallpaperX = changingTarget.mWallpaperX;
1701 }
1702 if (target.mWallpaperY >= 0) {
1703 mLastWallpaperY = target.mWallpaperY;
1704 } else if (changingTarget.mWallpaperY >= 0) {
1705 mLastWallpaperY = changingTarget.mWallpaperY;
1706 }
1707 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001708
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001709 int curTokenIndex = mWallpaperTokens.size();
1710 while (curTokenIndex > 0) {
1711 curTokenIndex--;
1712 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1713 int curWallpaperIndex = token.windows.size();
1714 while (curWallpaperIndex > 0) {
1715 curWallpaperIndex--;
1716 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1717 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1718 wallpaper.computeShownFrameLocked();
1719 changed = true;
1720 // We only want to be synchronous with one wallpaper.
1721 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001722 }
1723 }
1724 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001725
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001726 return changed;
1727 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001728
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001729 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001730 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001731 final int dw = mDisplay.getWidth();
1732 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001733
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001734 int curTokenIndex = mWallpaperTokens.size();
1735 while (curTokenIndex > 0) {
1736 curTokenIndex--;
1737 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001738 if (token.hidden == visible) {
1739 token.hidden = !visible;
1740 // Need to do a layout to ensure the wallpaper now has the
1741 // correct size.
1742 mLayoutNeeded = true;
1743 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001744
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001745 int curWallpaperIndex = token.windows.size();
1746 while (curWallpaperIndex > 0) {
1747 curWallpaperIndex--;
1748 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1749 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001750 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001751 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001752
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001753 if (wallpaper.mWallpaperVisible != visible) {
1754 wallpaper.mWallpaperVisible = visible;
1755 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001756 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001757 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001758 + ": " + visible);
1759 wallpaper.mClient.dispatchAppVisibility(visible);
1760 } catch (RemoteException e) {
1761 }
1762 }
1763 }
1764 }
1765 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001766
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001767 void sendPointerToWallpaperLocked(WindowState srcWin,
1768 MotionEvent pointer, long eventTime) {
1769 int curTokenIndex = mWallpaperTokens.size();
1770 while (curTokenIndex > 0) {
1771 curTokenIndex--;
1772 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1773 int curWallpaperIndex = token.windows.size();
1774 while (curWallpaperIndex > 0) {
1775 curWallpaperIndex--;
1776 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1777 if ((wallpaper.mAttrs.flags &
1778 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
1779 continue;
1780 }
1781 try {
1782 MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
Dianne Hackborn6adba242009-11-10 11:10:09 -08001783 if (srcWin != null) {
1784 ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
1785 srcWin.mFrame.top-wallpaper.mFrame.top);
1786 } else {
1787 ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
1788 }
1789 switch (pointer.getAction()) {
1790 case MotionEvent.ACTION_DOWN:
1791 mSendingPointersToWallpaper = true;
1792 break;
1793 case MotionEvent.ACTION_UP:
1794 mSendingPointersToWallpaper = false;
1795 break;
1796 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001797 wallpaper.mClient.dispatchPointer(ev, eventTime, false);
1798 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001799 Slog.w(TAG, "Failure sending pointer to wallpaper", e);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001800 }
1801 }
1802 }
1803 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001804
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001805 void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
1806 MotionEvent pointer, long eventTime, boolean skipped) {
1807 if (relWin != null) {
1808 mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
1809 } else {
1810 mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
1811 }
1812
1813 // If we sent an initial down to the wallpaper, then continue
1814 // sending events until the final up.
1815 if (mSendingPointersToWallpaper) {
1816 if (skipped) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001817 Slog.i(TAG, "Sending skipped pointer to wallpaper!");
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001818 }
1819 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1820
1821 // If we are on top of the wallpaper, then the wallpaper also
1822 // gets to see this movement.
1823 } else if (srcWin != null
1824 && pointer.getAction() == MotionEvent.ACTION_DOWN
1825 && mWallpaperTarget == srcWin
1826 && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
1827 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1828 }
1829 }
1830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 public int addWindow(Session session, IWindow client,
1832 WindowManager.LayoutParams attrs, int viewVisibility,
1833 Rect outContentInsets) {
1834 int res = mPolicy.checkAddPermission(attrs);
1835 if (res != WindowManagerImpl.ADD_OKAY) {
1836 return res;
1837 }
Romain Guy06882f82009-06-10 13:36:04 -07001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 boolean reportNewConfig = false;
1840 WindowState attachedWindow = null;
1841 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 synchronized(mWindowMap) {
1844 // Instantiating a Display requires talking with the simulator,
1845 // so don't do it until we know the system is mostly up and
1846 // running.
1847 if (mDisplay == null) {
1848 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1849 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001850 mInitialDisplayWidth = mDisplay.getWidth();
1851 mInitialDisplayHeight = mDisplay.getHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 mQueue.setDisplay(mDisplay);
1853 reportNewConfig = true;
1854 }
Romain Guy06882f82009-06-10 13:36:04 -07001855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001857 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001858 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1859 }
1860
1861 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001862 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 + attrs.token + ". Aborting.");
1866 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1867 }
1868 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1869 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 + attrs.token + ". Aborting.");
1872 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1873 }
1874 }
1875
1876 boolean addToken = false;
1877 WindowToken token = mTokenMap.get(attrs.token);
1878 if (token == null) {
1879 if (attrs.type >= FIRST_APPLICATION_WINDOW
1880 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001881 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 + attrs.token + ". Aborting.");
1883 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1884 }
1885 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001886 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 + attrs.token + ". Aborting.");
1888 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1889 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001890 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001891 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001892 + attrs.token + ". Aborting.");
1893 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 token = new WindowToken(attrs.token, -1, false);
1896 addToken = true;
1897 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1898 && attrs.type <= LAST_APPLICATION_WINDOW) {
1899 AppWindowToken atoken = token.appWindowToken;
1900 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001902 + token + ". Aborting.");
1903 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1904 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001905 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 + token + ". Aborting.");
1907 return WindowManagerImpl.ADD_APP_EXITING;
1908 }
1909 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1910 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001911 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1913 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1914 }
1915 } else if (attrs.type == TYPE_INPUT_METHOD) {
1916 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001917 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 + attrs.token + ". Aborting.");
1919 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1920 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001921 } else if (attrs.type == TYPE_WALLPAPER) {
1922 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001923 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001924 + attrs.token + ". Aborting.");
1925 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001927 }
1928
1929 win = new WindowState(session, client, token,
1930 attachedWindow, attrs, viewVisibility);
1931 if (win.mDeathRecipient == null) {
1932 // Client has apparently died, so there is no reason to
1933 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001934 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 + " that is dead, aborting.");
1936 return WindowManagerImpl.ADD_APP_EXITING;
1937 }
1938
1939 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001941 res = mPolicy.prepareAddWindowLw(win, attrs);
1942 if (res != WindowManagerImpl.ADD_OKAY) {
1943 return res;
1944 }
1945
1946 // From now on, no exceptions or errors allowed!
1947
1948 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07001949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001950 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07001951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 if (addToken) {
1953 mTokenMap.put(attrs.token, token);
1954 mTokenList.add(token);
1955 }
1956 win.attach();
1957 mWindowMap.put(client.asBinder(), win);
1958
1959 if (attrs.type == TYPE_APPLICATION_STARTING &&
1960 token.appWindowToken != null) {
1961 token.appWindowToken.startingWindow = win;
1962 }
1963
1964 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07001965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 if (attrs.type == TYPE_INPUT_METHOD) {
1967 mInputMethodWindow = win;
1968 addInputMethodWindowToListLocked(win);
1969 imMayMove = false;
1970 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
1971 mInputMethodDialogs.add(win);
1972 addWindowToListInOrderLocked(win, true);
1973 adjustInputMethodDialogsLocked();
1974 imMayMove = false;
1975 } else {
1976 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001977 if (attrs.type == TYPE_WALLPAPER) {
1978 mLastWallpaperTimeoutTime = 0;
1979 adjustWallpaperWindowsLocked();
1980 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001981 adjustWallpaperWindowsLocked();
1982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 }
Romain Guy06882f82009-06-10 13:36:04 -07001984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07001986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07001988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 if (mInTouchMode) {
1990 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
1991 }
1992 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
1993 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
1994 }
Romain Guy06882f82009-06-10 13:36:04 -07001995
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08001996 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 if (win.canReceiveKeys()) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08001998 if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
1999 == true) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002000 imMayMove = false;
2001 }
2002 }
Romain Guy06882f82009-06-10 13:36:04 -07002003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002005 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 }
Romain Guy06882f82009-06-10 13:36:04 -07002007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 assignLayersLocked();
2009 // Don't do layout here, the window must call
2010 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 //dump();
2013
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002014 if (focusChanged) {
2015 if (mCurrentFocus != null) {
2016 mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
2017 }
2018 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002019 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 TAG, "New client " + client.asBinder()
2021 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002022
2023 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2024 reportNewConfig = true;
2025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002026 }
2027
2028 // sendNewConfiguration() checks caller permissions so we must call it with
2029 // privilege. updateOrientationFromAppTokens() clears and resets the caller
2030 // identity anyway, so it's safe to just clear & restore around this whole
2031 // block.
2032 final long origId = Binder.clearCallingIdentity();
2033 if (reportNewConfig) {
2034 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035 }
2036 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 return res;
2039 }
Romain Guy06882f82009-06-10 13:36:04 -07002040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 public void removeWindow(Session session, IWindow client) {
2042 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002043 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 if (win == null) {
2045 return;
2046 }
2047 removeWindowLocked(session, win);
2048 }
2049 }
Romain Guy06882f82009-06-10 13:36:04 -07002050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 public void removeWindowLocked(Session session, WindowState win) {
2052
Joe Onorato8a9b2202010-02-26 18:56:32 -08002053 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002054 TAG, "Remove " + win + " client="
2055 + Integer.toHexString(System.identityHashCode(
2056 win.mClient.asBinder()))
2057 + ", surface=" + win.mSurface);
2058
2059 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002060
Joe Onorato8a9b2202010-02-26 18:56:32 -08002061 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002062 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2063 + " mExiting=" + win.mExiting
2064 + " isAnimating=" + win.isAnimating()
2065 + " app-animation="
2066 + (win.mAppToken != null ? win.mAppToken.animation : null)
2067 + " inPendingTransaction="
2068 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2069 + " mDisplayFrozen=" + mDisplayFrozen);
2070 // Visibility of the removed window. Will be used later to update orientation later on.
2071 boolean wasVisible = false;
2072 // First, see if we need to run an animation. If we do, we have
2073 // to hold off on removing the window until the animation is done.
2074 // If the display is frozen, just remove immediately, since the
2075 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002076 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 // If we are not currently running the exit animation, we
2078 // need to see about starting one.
2079 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002081 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2082 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2083 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2084 }
2085 // Try starting an animation.
2086 if (applyAnimationLocked(win, transit, false)) {
2087 win.mExiting = true;
2088 }
2089 }
2090 if (win.mExiting || win.isAnimating()) {
2091 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002092 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 win.mExiting = true;
2094 win.mRemoveOnExit = true;
2095 mLayoutNeeded = true;
2096 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2097 performLayoutAndPlaceSurfacesLocked();
2098 if (win.mAppToken != null) {
2099 win.mAppToken.updateReportedVisibilityLocked();
2100 }
2101 //dump();
2102 Binder.restoreCallingIdentity(origId);
2103 return;
2104 }
2105 }
2106
2107 removeWindowInnerLocked(session, win);
2108 // Removing a visible window will effect the computed orientation
2109 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002110 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002111 != mForcedAppOrientation
2112 && updateOrientationFromAppTokensLocked()) {
2113 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
2115 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2116 Binder.restoreCallingIdentity(origId);
2117 }
Romain Guy06882f82009-06-10 13:36:04 -07002118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07002120 mKeyWaiter.finishedKey(session, win.mClient, true,
2121 KeyWaiter.RETURN_NOTHING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 mKeyWaiter.releasePendingPointerLocked(win.mSession);
2123 mKeyWaiter.releasePendingTrackballLocked(win.mSession);
Romain Guy06882f82009-06-10 13:36:04 -07002124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002127 if (mInputMethodTarget == win) {
2128 moveInputMethodWindowsIfNeededLocked(false);
2129 }
Romain Guy06882f82009-06-10 13:36:04 -07002130
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002131 if (false) {
2132 RuntimeException e = new RuntimeException("here");
2133 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002135 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 mPolicy.removeWindowLw(win);
2138 win.removeLocked();
2139
2140 mWindowMap.remove(win.mClient.asBinder());
2141 mWindows.remove(win);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002142 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143
2144 if (mInputMethodWindow == win) {
2145 mInputMethodWindow = null;
2146 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2147 mInputMethodDialogs.remove(win);
2148 }
Romain Guy06882f82009-06-10 13:36:04 -07002149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 final WindowToken token = win.mToken;
2151 final AppWindowToken atoken = win.mAppToken;
2152 token.windows.remove(win);
2153 if (atoken != null) {
2154 atoken.allAppWindows.remove(win);
2155 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002156 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 TAG, "**** Removing window " + win + ": count="
2158 + token.windows.size());
2159 if (token.windows.size() == 0) {
2160 if (!token.explicit) {
2161 mTokenMap.remove(token.token);
2162 mTokenList.remove(token);
2163 } else if (atoken != null) {
2164 atoken.firstWindowDrawn = false;
2165 }
2166 }
2167
2168 if (atoken != null) {
2169 if (atoken.startingWindow == win) {
2170 atoken.startingWindow = null;
2171 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2172 // If this is the last window and we had requested a starting
2173 // transition window, well there is no point now.
2174 atoken.startingData = null;
2175 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2176 // If this is the last window except for a starting transition
2177 // window, we need to get rid of the starting transition.
2178 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002179 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180 + ": no more real windows");
2181 }
2182 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2183 mH.sendMessage(m);
2184 }
2185 }
Romain Guy06882f82009-06-10 13:36:04 -07002186
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002187 if (win.mAttrs.type == TYPE_WALLPAPER) {
2188 mLastWallpaperTimeoutTime = 0;
2189 adjustWallpaperWindowsLocked();
2190 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002191 adjustWallpaperWindowsLocked();
2192 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002194 if (!mInLayout) {
2195 assignLayersLocked();
2196 mLayoutNeeded = true;
2197 performLayoutAndPlaceSurfacesLocked();
2198 if (win.mAppToken != null) {
2199 win.mAppToken.updateReportedVisibilityLocked();
2200 }
2201 }
2202 }
2203
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002204 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2205 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2206 + ": " + msg + " / " + w.mAttrs.getTitle();
2207 if (where != null) {
2208 Slog.i(TAG, str, where);
2209 } else {
2210 Slog.i(TAG, str);
2211 }
2212 }
2213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2215 long origId = Binder.clearCallingIdentity();
2216 try {
2217 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002218 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002219 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002220 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 Surface.openTransaction();
2222 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002223 if (SHOW_TRANSACTIONS) logSurface(w,
2224 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002225 w.mSurface.setTransparentRegionHint(region);
2226 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002227 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 Surface.closeTransaction();
2229 }
2230 }
2231 }
2232 } finally {
2233 Binder.restoreCallingIdentity(origId);
2234 }
2235 }
2236
2237 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002238 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002239 Rect visibleInsets) {
2240 long origId = Binder.clearCallingIdentity();
2241 try {
2242 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002243 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 if (w != null) {
2245 w.mGivenInsetsPending = false;
2246 w.mGivenContentInsets.set(contentInsets);
2247 w.mGivenVisibleInsets.set(visibleInsets);
2248 w.mTouchableInsets = touchableInsets;
2249 mLayoutNeeded = true;
2250 performLayoutAndPlaceSurfacesLocked();
2251 }
2252 }
2253 } finally {
2254 Binder.restoreCallingIdentity(origId);
2255 }
2256 }
Romain Guy06882f82009-06-10 13:36:04 -07002257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 public void getWindowDisplayFrame(Session session, IWindow client,
2259 Rect outDisplayFrame) {
2260 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002261 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 if (win == null) {
2263 outDisplayFrame.setEmpty();
2264 return;
2265 }
2266 outDisplayFrame.set(win.mDisplayFrame);
2267 }
2268 }
2269
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002270 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2271 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002272 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2273 window.mWallpaperX = x;
2274 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002275 window.mWallpaperXStep = xStep;
2276 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002277 if (updateWallpaperOffsetLocked(window, true)) {
2278 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002279 }
2280 }
2281 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002282
Dianne Hackborn75804932009-10-20 20:15:20 -07002283 void wallpaperCommandComplete(IBinder window, Bundle result) {
2284 synchronized (mWindowMap) {
2285 if (mWaitingOnWallpaper != null &&
2286 mWaitingOnWallpaper.mClient.asBinder() == window) {
2287 mWaitingOnWallpaper = null;
2288 mWindowMap.notifyAll();
2289 }
2290 }
2291 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002292
Dianne Hackborn75804932009-10-20 20:15:20 -07002293 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2294 String action, int x, int y, int z, Bundle extras, boolean sync) {
2295 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2296 || window == mUpperWallpaperTarget) {
2297 boolean doWait = sync;
2298 int curTokenIndex = mWallpaperTokens.size();
2299 while (curTokenIndex > 0) {
2300 curTokenIndex--;
2301 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2302 int curWallpaperIndex = token.windows.size();
2303 while (curWallpaperIndex > 0) {
2304 curWallpaperIndex--;
2305 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2306 try {
2307 wallpaper.mClient.dispatchWallpaperCommand(action,
2308 x, y, z, extras, sync);
2309 // We only want to be synchronous with one wallpaper.
2310 sync = false;
2311 } catch (RemoteException e) {
2312 }
2313 }
2314 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002315
Dianne Hackborn75804932009-10-20 20:15:20 -07002316 if (doWait) {
2317 // XXX Need to wait for result.
2318 }
2319 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002320
Dianne Hackborn75804932009-10-20 20:15:20 -07002321 return null;
2322 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 public int relayoutWindow(Session session, IWindow client,
2325 WindowManager.LayoutParams attrs, int requestedWidth,
2326 int requestedHeight, int viewVisibility, boolean insetsPending,
2327 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002328 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 boolean displayed = false;
2330 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002331 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002335 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 if (win == null) {
2337 return 0;
2338 }
2339 win.mRequestedWidth = requestedWidth;
2340 win.mRequestedHeight = requestedHeight;
2341
2342 if (attrs != null) {
2343 mPolicy.adjustWindowParamsLw(attrs);
2344 }
Romain Guy06882f82009-06-10 13:36:04 -07002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 int attrChanges = 0;
2347 int flagChanges = 0;
2348 if (attrs != null) {
2349 flagChanges = win.mAttrs.flags ^= attrs.flags;
2350 attrChanges = win.mAttrs.copyFrom(attrs);
2351 }
2352
Joe Onorato8a9b2202010-02-26 18:56:32 -08002353 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354
2355 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2356 win.mAlpha = attrs.alpha;
2357 }
2358
2359 final boolean scaledWindow =
2360 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2361
2362 if (scaledWindow) {
2363 // requested{Width|Height} Surface's physical size
2364 // attrs.{width|height} Size on screen
2365 win.mHScale = (attrs.width != requestedWidth) ?
2366 (attrs.width / (float)requestedWidth) : 1.0f;
2367 win.mVScale = (attrs.height != requestedHeight) ?
2368 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002369 } else {
2370 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 }
2372
2373 boolean imMayMove = (flagChanges&(
2374 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2375 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 boolean focusMayChange = win.mViewVisibility != viewVisibility
2378 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2379 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002380
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002381 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2382 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 win.mRelayoutCalled = true;
2385 final int oldVisibility = win.mViewVisibility;
2386 win.mViewVisibility = viewVisibility;
2387 if (viewVisibility == View.VISIBLE &&
2388 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2389 displayed = !win.isVisibleLw();
2390 if (win.mExiting) {
2391 win.mExiting = false;
2392 win.mAnimation = null;
2393 }
2394 if (win.mDestroying) {
2395 win.mDestroying = false;
2396 mDestroySurface.remove(win);
2397 }
2398 if (oldVisibility == View.GONE) {
2399 win.mEnterAnimationPending = true;
2400 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002401 if (displayed) {
2402 if (win.mSurface != null && !win.mDrawPending
2403 && !win.mCommitDrawPending && !mDisplayFrozen
2404 && mPolicy.isScreenOn()) {
2405 applyEnterAnimationLocked(win);
2406 }
2407 if ((win.mAttrs.flags
2408 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2409 if (DEBUG_VISIBILITY) Slog.v(TAG,
2410 "Relayout window turning screen on: " + win);
2411 win.mTurnOnScreen = true;
2412 }
2413 int diff = 0;
2414 if (win.mConfiguration != mCurConfiguration
2415 && (win.mConfiguration == null
2416 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2417 win.mConfiguration = mCurConfiguration;
2418 if (DEBUG_CONFIGURATION) {
2419 Slog.i(TAG, "Window " + win + " visible with new config: "
2420 + win.mConfiguration + " / 0x"
2421 + Integer.toHexString(diff));
2422 }
2423 outConfig.setTo(mCurConfiguration);
2424 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2427 // To change the format, we need to re-build the surface.
2428 win.destroySurfaceLocked();
2429 displayed = true;
2430 }
2431 try {
2432 Surface surface = win.createSurfaceLocked();
2433 if (surface != null) {
2434 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002435 win.mReportDestroySurface = false;
2436 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002437 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002438 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002440 // For some reason there isn't a surface. Clear the
2441 // caller's object so they see the same state.
2442 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 }
2444 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002445 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002446 + client + " (" + win.mAttrs.getTitle() + ")",
2447 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 Binder.restoreCallingIdentity(origId);
2449 return 0;
2450 }
2451 if (displayed) {
2452 focusMayChange = true;
2453 }
2454 if (win.mAttrs.type == TYPE_INPUT_METHOD
2455 && mInputMethodWindow == null) {
2456 mInputMethodWindow = win;
2457 imMayMove = true;
2458 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002459 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2460 && win.mAppToken != null
2461 && win.mAppToken.startingWindow != null) {
2462 // Special handling of starting window over the base
2463 // window of the app: propagate lock screen flags to it,
2464 // to provide the correct semantics while starting.
2465 final int mask =
2466 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002467 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2468 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002469 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2470 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 } else {
2473 win.mEnterAnimationPending = false;
2474 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002475 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002476 + ": mExiting=" + win.mExiting
2477 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 // If we are not currently running the exit animation, we
2479 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002480 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 // Try starting an animation; if there isn't one, we
2482 // can destroy the surface right away.
2483 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2484 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2485 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2486 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002487 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002489 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 win.mExiting = true;
2491 mKeyWaiter.finishedKey(session, client, true,
2492 KeyWaiter.RETURN_NOTHING);
2493 } else if (win.isAnimating()) {
2494 // Currently in a hide animation... turn this into
2495 // an exit.
2496 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002497 } else if (win == mWallpaperTarget) {
2498 // If the wallpaper is currently behind this
2499 // window, we need to change both of them inside
2500 // of a transaction to avoid artifacts.
2501 win.mExiting = true;
2502 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 } else {
2504 if (mInputMethodWindow == win) {
2505 mInputMethodWindow = null;
2506 }
2507 win.destroySurfaceLocked();
2508 }
2509 }
2510 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002511
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002512 if (win.mSurface == null || (win.getAttrs().flags
2513 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2514 || win.mSurfacePendingDestroy) {
2515 // We are being called from a local process, which
2516 // means outSurface holds its current surface. Ensure the
2517 // surface object is cleared, but we don't want it actually
2518 // destroyed at this point.
2519 win.mSurfacePendingDestroy = false;
2520 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002521 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002522 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002523 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002524 "Keeping surface, will report destroy: " + win);
2525 win.mReportDestroySurface = true;
2526 outSurface.copyFrom(win.mSurface);
2527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528 }
2529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 if (focusMayChange) {
2531 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2532 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002533 imMayMove = false;
2534 }
2535 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2536 }
Romain Guy06882f82009-06-10 13:36:04 -07002537
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002538 // updateFocusedWindowLocked() already assigned layers so we only need to
2539 // reassign them at this point if the IM window state gets shuffled
2540 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002543 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2544 // Little hack here -- we -should- be able to rely on the
2545 // function to return true if the IME has moved and needs
2546 // its layer recomputed. However, if the IME was hidden
2547 // and isn't actually moved in the list, its layer may be
2548 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 assignLayers = true;
2550 }
2551 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002552 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002553 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002554 assignLayers = true;
2555 }
2556 }
Romain Guy06882f82009-06-10 13:36:04 -07002557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002558 mLayoutNeeded = true;
2559 win.mGivenInsetsPending = insetsPending;
2560 if (assignLayers) {
2561 assignLayersLocked();
2562 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002563 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002565 if (displayed && win.mIsWallpaper) {
2566 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002567 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 if (win.mAppToken != null) {
2570 win.mAppToken.updateReportedVisibilityLocked();
2571 }
2572 outFrame.set(win.mFrame);
2573 outContentInsets.set(win.mContentInsets);
2574 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002575 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002577 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 + ", requestedHeight=" + requestedHeight
2579 + ", viewVisibility=" + viewVisibility
2580 + "\nRelayout returning frame=" + outFrame
2581 + ", surface=" + outSurface);
2582
Joe Onorato8a9b2202010-02-26 18:56:32 -08002583 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2585
2586 inTouchMode = mInTouchMode;
2587 }
2588
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002589 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 sendNewConfiguration();
2591 }
Romain Guy06882f82009-06-10 13:36:04 -07002592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2596 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2597 }
2598
2599 public void finishDrawingWindow(Session session, IWindow client) {
2600 final long origId = Binder.clearCallingIdentity();
2601 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002602 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002604 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2605 adjustWallpaperWindowsLocked();
2606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 mLayoutNeeded = true;
2608 performLayoutAndPlaceSurfacesLocked();
2609 }
2610 }
2611 Binder.restoreCallingIdentity(origId);
2612 }
2613
2614 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002615 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 + (lp != null ? lp.packageName : null)
2617 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2618 if (lp != null && lp.windowAnimations != 0) {
2619 // If this is a system resource, don't try to load it from the
2620 // application resources. It is nice to avoid loading application
2621 // resources if we can.
2622 String packageName = lp.packageName != null ? lp.packageName : "android";
2623 int resId = lp.windowAnimations;
2624 if ((resId&0xFF000000) == 0x01000000) {
2625 packageName = "android";
2626 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002627 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 + packageName);
2629 return AttributeCache.instance().get(packageName, resId,
2630 com.android.internal.R.styleable.WindowAnimation);
2631 }
2632 return null;
2633 }
Romain Guy06882f82009-06-10 13:36:04 -07002634
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002635 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002636 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002637 + packageName + " resId=0x" + Integer.toHexString(resId));
2638 if (packageName != null) {
2639 if ((resId&0xFF000000) == 0x01000000) {
2640 packageName = "android";
2641 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002642 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002643 + packageName);
2644 return AttributeCache.instance().get(packageName, resId,
2645 com.android.internal.R.styleable.WindowAnimation);
2646 }
2647 return null;
2648 }
2649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002650 private void applyEnterAnimationLocked(WindowState win) {
2651 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2652 if (win.mEnterAnimationPending) {
2653 win.mEnterAnimationPending = false;
2654 transit = WindowManagerPolicy.TRANSIT_ENTER;
2655 }
2656
2657 applyAnimationLocked(win, transit, true);
2658 }
2659
2660 private boolean applyAnimationLocked(WindowState win,
2661 int transit, boolean isEntrance) {
2662 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2663 // If we are trying to apply an animation, but already running
2664 // an animation of the same type, then just leave that one alone.
2665 return true;
2666 }
Romain Guy06882f82009-06-10 13:36:04 -07002667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 // Only apply an animation if the display isn't frozen. If it is
2669 // frozen, there is no reason to animate and it can cause strange
2670 // artifacts when we unfreeze the display if some different animation
2671 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002672 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 int anim = mPolicy.selectAnimationLw(win, transit);
2674 int attr = -1;
2675 Animation a = null;
2676 if (anim != 0) {
2677 a = AnimationUtils.loadAnimation(mContext, anim);
2678 } else {
2679 switch (transit) {
2680 case WindowManagerPolicy.TRANSIT_ENTER:
2681 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2682 break;
2683 case WindowManagerPolicy.TRANSIT_EXIT:
2684 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2685 break;
2686 case WindowManagerPolicy.TRANSIT_SHOW:
2687 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2688 break;
2689 case WindowManagerPolicy.TRANSIT_HIDE:
2690 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2691 break;
2692 }
2693 if (attr >= 0) {
2694 a = loadAnimation(win.mAttrs, attr);
2695 }
2696 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002697 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2699 + " mAnimation=" + win.mAnimation
2700 + " isEntrance=" + isEntrance);
2701 if (a != null) {
2702 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002703 RuntimeException e = null;
2704 if (!HIDE_STACK_CRAWLS) {
2705 e = new RuntimeException();
2706 e.fillInStackTrace();
2707 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002708 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 }
2710 win.setAnimation(a);
2711 win.mAnimationIsEntrance = isEntrance;
2712 }
2713 } else {
2714 win.clearAnimation();
2715 }
2716
2717 return win.mAnimation != null;
2718 }
2719
2720 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2721 int anim = 0;
2722 Context context = mContext;
2723 if (animAttr >= 0) {
2724 AttributeCache.Entry ent = getCachedAnimations(lp);
2725 if (ent != null) {
2726 context = ent.context;
2727 anim = ent.array.getResourceId(animAttr, 0);
2728 }
2729 }
2730 if (anim != 0) {
2731 return AnimationUtils.loadAnimation(context, anim);
2732 }
2733 return null;
2734 }
Romain Guy06882f82009-06-10 13:36:04 -07002735
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002736 private Animation loadAnimation(String packageName, int resId) {
2737 int anim = 0;
2738 Context context = mContext;
2739 if (resId >= 0) {
2740 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2741 if (ent != null) {
2742 context = ent.context;
2743 anim = resId;
2744 }
2745 }
2746 if (anim != 0) {
2747 return AnimationUtils.loadAnimation(context, anim);
2748 }
2749 return null;
2750 }
2751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 private boolean applyAnimationLocked(AppWindowToken wtoken,
2753 WindowManager.LayoutParams lp, int transit, boolean enter) {
2754 // Only apply an animation if the display isn't frozen. If it is
2755 // frozen, there is no reason to animate and it can cause strange
2756 // artifacts when we unfreeze the display if some different animation
2757 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002758 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002759 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002760 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002761 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002762 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002763 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002764 } else if (mNextAppTransitionPackage != null) {
2765 a = loadAnimation(mNextAppTransitionPackage, enter ?
2766 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002767 } else {
2768 int animAttr = 0;
2769 switch (transit) {
2770 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2771 animAttr = enter
2772 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2773 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2774 break;
2775 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2776 animAttr = enter
2777 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2778 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2779 break;
2780 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2781 animAttr = enter
2782 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2783 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2784 break;
2785 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2786 animAttr = enter
2787 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2788 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2789 break;
2790 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2791 animAttr = enter
2792 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2793 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2794 break;
2795 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2796 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002797 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002798 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2799 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002800 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002801 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002802 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2803 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002804 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002805 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002806 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002807 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2808 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2809 break;
2810 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2811 animAttr = enter
2812 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2813 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2814 break;
2815 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2816 animAttr = enter
2817 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2818 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002819 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002820 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002821 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002822 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002823 + " anim=" + a
2824 + " animAttr=0x" + Integer.toHexString(animAttr)
2825 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 if (a != null) {
2828 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002829 RuntimeException e = null;
2830 if (!HIDE_STACK_CRAWLS) {
2831 e = new RuntimeException();
2832 e.fillInStackTrace();
2833 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002834 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 }
2836 wtoken.setAnimation(a);
2837 }
2838 } else {
2839 wtoken.clearAnimation();
2840 }
2841
2842 return wtoken.animation != null;
2843 }
2844
2845 // -------------------------------------------------------------
2846 // Application Window Tokens
2847 // -------------------------------------------------------------
2848
2849 public void validateAppTokens(List tokens) {
2850 int v = tokens.size()-1;
2851 int m = mAppTokens.size()-1;
2852 while (v >= 0 && m >= 0) {
2853 AppWindowToken wtoken = mAppTokens.get(m);
2854 if (wtoken.removed) {
2855 m--;
2856 continue;
2857 }
2858 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002859 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2861 }
2862 v--;
2863 m--;
2864 }
2865 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002866 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002867 v--;
2868 }
2869 while (m >= 0) {
2870 AppWindowToken wtoken = mAppTokens.get(m);
2871 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002872 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 }
2874 m--;
2875 }
2876 }
2877
2878 boolean checkCallingPermission(String permission, String func) {
2879 // Quick check: if the calling permission is me, it's all okay.
2880 if (Binder.getCallingPid() == Process.myPid()) {
2881 return true;
2882 }
Romain Guy06882f82009-06-10 13:36:04 -07002883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002884 if (mContext.checkCallingPermission(permission)
2885 == PackageManager.PERMISSION_GRANTED) {
2886 return true;
2887 }
2888 String msg = "Permission Denial: " + func + " from pid="
2889 + Binder.getCallingPid()
2890 + ", uid=" + Binder.getCallingUid()
2891 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002892 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 return false;
2894 }
Romain Guy06882f82009-06-10 13:36:04 -07002895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 AppWindowToken findAppWindowToken(IBinder token) {
2897 WindowToken wtoken = mTokenMap.get(token);
2898 if (wtoken == null) {
2899 return null;
2900 }
2901 return wtoken.appWindowToken;
2902 }
Romain Guy06882f82009-06-10 13:36:04 -07002903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002904 public void addWindowToken(IBinder token, int type) {
2905 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2906 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002907 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002908 }
Romain Guy06882f82009-06-10 13:36:04 -07002909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 synchronized(mWindowMap) {
2911 WindowToken wtoken = mTokenMap.get(token);
2912 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002913 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 return;
2915 }
2916 wtoken = new WindowToken(token, type, true);
2917 mTokenMap.put(token, wtoken);
2918 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002919 if (type == TYPE_WALLPAPER) {
2920 mWallpaperTokens.add(wtoken);
2921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
2923 }
Romain Guy06882f82009-06-10 13:36:04 -07002924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 public void removeWindowToken(IBinder token) {
2926 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2927 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002928 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 }
2930
2931 final long origId = Binder.clearCallingIdentity();
2932 synchronized(mWindowMap) {
2933 WindowToken wtoken = mTokenMap.remove(token);
2934 mTokenList.remove(wtoken);
2935 if (wtoken != null) {
2936 boolean delayed = false;
2937 if (!wtoken.hidden) {
2938 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07002939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 final int N = wtoken.windows.size();
2941 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07002942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 for (int i=0; i<N; i++) {
2944 WindowState win = wtoken.windows.get(i);
2945
2946 if (win.isAnimating()) {
2947 delayed = true;
2948 }
Romain Guy06882f82009-06-10 13:36:04 -07002949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950 if (win.isVisibleNow()) {
2951 applyAnimationLocked(win,
2952 WindowManagerPolicy.TRANSIT_EXIT, false);
2953 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
2954 KeyWaiter.RETURN_NOTHING);
2955 changed = true;
2956 }
2957 }
2958
2959 if (changed) {
2960 mLayoutNeeded = true;
2961 performLayoutAndPlaceSurfacesLocked();
2962 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2963 }
Romain Guy06882f82009-06-10 13:36:04 -07002964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 if (delayed) {
2966 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002967 } else if (wtoken.windowType == TYPE_WALLPAPER) {
2968 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002969 }
2970 }
Romain Guy06882f82009-06-10 13:36:04 -07002971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002973 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 }
2975 }
2976 Binder.restoreCallingIdentity(origId);
2977 }
2978
2979 public void addAppToken(int addPos, IApplicationToken token,
2980 int groupId, int requestedOrientation, boolean fullscreen) {
2981 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2982 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002983 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 }
Romain Guy06882f82009-06-10 13:36:04 -07002985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 synchronized(mWindowMap) {
2987 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
2988 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002989 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 return;
2991 }
2992 wtoken = new AppWindowToken(token);
2993 wtoken.groupId = groupId;
2994 wtoken.appFullscreen = fullscreen;
2995 wtoken.requestedOrientation = requestedOrientation;
2996 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002997 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 mTokenMap.put(token.asBinder(), wtoken);
2999 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 // Application tokens start out hidden.
3002 wtoken.hidden = true;
3003 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 //dump();
3006 }
3007 }
Romain Guy06882f82009-06-10 13:36:04 -07003008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003009 public void setAppGroupId(IBinder token, int groupId) {
3010 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3011 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003012 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013 }
3014
3015 synchronized(mWindowMap) {
3016 AppWindowToken wtoken = findAppWindowToken(token);
3017 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003018 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 return;
3020 }
3021 wtoken.groupId = groupId;
3022 }
3023 }
Romain Guy06882f82009-06-10 13:36:04 -07003024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 public int getOrientationFromWindowsLocked() {
3026 int pos = mWindows.size() - 1;
3027 while (pos >= 0) {
3028 WindowState wtoken = (WindowState) mWindows.get(pos);
3029 pos--;
3030 if (wtoken.mAppToken != null) {
3031 // We hit an application window. so the orientation will be determined by the
3032 // app window. No point in continuing further.
3033 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3034 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003035 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 continue;
3037 }
3038 int req = wtoken.mAttrs.screenOrientation;
3039 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3040 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3041 continue;
3042 } else {
3043 return req;
3044 }
3045 }
3046 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3047 }
Romain Guy06882f82009-06-10 13:36:04 -07003048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003050 int pos = mAppTokens.size() - 1;
3051 int curGroup = 0;
3052 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3053 boolean findingBehind = false;
3054 boolean haveGroup = false;
3055 boolean lastFullscreen = false;
3056 while (pos >= 0) {
3057 AppWindowToken wtoken = mAppTokens.get(pos);
3058 pos--;
3059 // if we're about to tear down this window and not seek for
3060 // the behind activity, don't use it for orientation
3061 if (!findingBehind
3062 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3063 continue;
3064 }
3065
3066 if (!haveGroup) {
3067 // We ignore any hidden applications on the top.
3068 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003069 continue;
3070 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003071 haveGroup = true;
3072 curGroup = wtoken.groupId;
3073 lastOrientation = wtoken.requestedOrientation;
3074 } else if (curGroup != wtoken.groupId) {
3075 // If we have hit a new application group, and the bottom
3076 // of the previous group didn't explicitly say to use
3077 // the orientation behind it, and the last app was
3078 // full screen, then we'll stick with the
3079 // user's orientation.
3080 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3081 && lastFullscreen) {
3082 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003085 int or = wtoken.requestedOrientation;
3086 // If this application is fullscreen, and didn't explicitly say
3087 // to use the orientation behind it, then just take whatever
3088 // orientation it has and ignores whatever is under it.
3089 lastFullscreen = wtoken.appFullscreen;
3090 if (lastFullscreen
3091 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3092 return or;
3093 }
3094 // If this application has requested an explicit orientation,
3095 // then use it.
3096 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3097 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3098 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3099 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3100 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3101 return or;
3102 }
3103 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3104 }
3105 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003106 }
Romain Guy06882f82009-06-10 13:36:04 -07003107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003108 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003109 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003110 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3111 "updateOrientationFromAppTokens()")) {
3112 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3113 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003114
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003115 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003117
3118 synchronized(mWindowMap) {
3119 if (updateOrientationFromAppTokensLocked()) {
3120 if (freezeThisOneIfNeeded != null) {
3121 AppWindowToken wtoken = findAppWindowToken(
3122 freezeThisOneIfNeeded);
3123 if (wtoken != null) {
3124 startAppFreezingScreenLocked(wtoken,
3125 ActivityInfo.CONFIG_ORIENTATION);
3126 }
3127 }
3128 config = computeNewConfigurationLocked();
3129
3130 } else if (currentConfig != null) {
3131 // No obvious action we need to take, but if our current
3132 // state mismatches the activity maanager's, update it
3133 mTempConfiguration.setToDefaults();
3134 if (computeNewConfigurationLocked(mTempConfiguration)) {
3135 if (currentConfig.diff(mTempConfiguration) != 0) {
3136 mWaitingForConfig = true;
3137 mLayoutNeeded = true;
3138 startFreezingDisplayLocked();
3139 config = new Configuration(mTempConfiguration);
3140 }
3141 }
3142 }
3143 }
3144
Dianne Hackborncfaef692009-06-15 14:24:44 -07003145 Binder.restoreCallingIdentity(ident);
3146 return config;
3147 }
3148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003150 * Determine the new desired orientation of the display, returning
3151 * a non-null new Configuration if it has changed from the current
3152 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3153 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3154 * SCREEN. This will typically be done for you if you call
3155 * sendNewConfiguration().
3156 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 * The orientation is computed from non-application windows first. If none of
3158 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003159 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3161 * android.os.IBinder)
3162 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003163 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003164 if (mDisplayFrozen) {
3165 // If the display is frozen, some activities may be in the middle
3166 // of restarting, and thus have removed their old window. If the
3167 // window has the flag to hide the lock screen, then the lock screen
3168 // can re-appear and inflict its own orientation on us. Keep the
3169 // orientation stable until this all settles down.
3170 return false;
3171 }
3172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 long ident = Binder.clearCallingIdentity();
3175 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003176 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 mForcedAppOrientation = req;
3180 //send a message to Policy indicating orientation change to take
3181 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003182 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003183 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3184 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3185 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 }
3187 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003188
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003189 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 } finally {
3191 Binder.restoreCallingIdentity(ident);
3192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 }
Romain Guy06882f82009-06-10 13:36:04 -07003194
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003195 int computeForcedAppOrientationLocked() {
3196 int req = getOrientationFromWindowsLocked();
3197 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3198 req = getOrientationFromAppTokensLocked();
3199 }
3200 return req;
3201 }
Romain Guy06882f82009-06-10 13:36:04 -07003202
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003203 public void setNewConfiguration(Configuration config) {
3204 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3205 "setNewConfiguration()")) {
3206 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3207 }
3208
3209 synchronized(mWindowMap) {
3210 mCurConfiguration = new Configuration(config);
3211 mWaitingForConfig = false;
3212 performLayoutAndPlaceSurfacesLocked();
3213 }
3214 }
3215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003216 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3217 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3218 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003219 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 }
Romain Guy06882f82009-06-10 13:36:04 -07003221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003222 synchronized(mWindowMap) {
3223 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3224 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003225 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 return;
3227 }
Romain Guy06882f82009-06-10 13:36:04 -07003228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 wtoken.requestedOrientation = requestedOrientation;
3230 }
3231 }
Romain Guy06882f82009-06-10 13:36:04 -07003232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 public int getAppOrientation(IApplicationToken token) {
3234 synchronized(mWindowMap) {
3235 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3236 if (wtoken == null) {
3237 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3238 }
Romain Guy06882f82009-06-10 13:36:04 -07003239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003240 return wtoken.requestedOrientation;
3241 }
3242 }
Romain Guy06882f82009-06-10 13:36:04 -07003243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003244 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3245 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3246 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003247 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 }
3249
3250 synchronized(mWindowMap) {
3251 boolean changed = false;
3252 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003253 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 changed = mFocusedApp != null;
3255 mFocusedApp = null;
3256 mKeyWaiter.tickle();
3257 } else {
3258 AppWindowToken newFocus = findAppWindowToken(token);
3259 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003260 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 return;
3262 }
3263 changed = mFocusedApp != newFocus;
3264 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003265 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003266 mKeyWaiter.tickle();
3267 }
3268
3269 if (moveFocusNow && changed) {
3270 final long origId = Binder.clearCallingIdentity();
3271 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3272 Binder.restoreCallingIdentity(origId);
3273 }
3274 }
3275 }
3276
3277 public void prepareAppTransition(int transit) {
3278 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3279 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003280 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003281 }
Romain Guy06882f82009-06-10 13:36:04 -07003282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003283 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003284 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 TAG, "Prepare app transition: transit=" + transit
3286 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003287 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003288 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3289 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003291 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3292 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3293 // Opening a new task always supersedes a close for the anim.
3294 mNextAppTransition = transit;
3295 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3296 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3297 // Opening a new activity always supersedes a close for the anim.
3298 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003299 }
3300 mAppTransitionReady = false;
3301 mAppTransitionTimeout = false;
3302 mStartingIconInTransition = false;
3303 mSkipAppTransitionAnimation = false;
3304 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3305 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3306 5000);
3307 }
3308 }
3309 }
3310
3311 public int getPendingAppTransition() {
3312 return mNextAppTransition;
3313 }
Romain Guy06882f82009-06-10 13:36:04 -07003314
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003315 public void overridePendingAppTransition(String packageName,
3316 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003317 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003318 mNextAppTransitionPackage = packageName;
3319 mNextAppTransitionEnter = enterAnim;
3320 mNextAppTransitionExit = exitAnim;
3321 }
3322 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 public void executeAppTransition() {
3325 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3326 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003327 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 }
Romain Guy06882f82009-06-10 13:36:04 -07003329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003331 if (DEBUG_APP_TRANSITIONS) {
3332 RuntimeException e = new RuntimeException("here");
3333 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003334 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003335 + mNextAppTransition, e);
3336 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003337 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 mAppTransitionReady = true;
3339 final long origId = Binder.clearCallingIdentity();
3340 performLayoutAndPlaceSurfacesLocked();
3341 Binder.restoreCallingIdentity(origId);
3342 }
3343 }
3344 }
3345
3346 public void setAppStartingWindow(IBinder token, String pkg,
3347 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3348 IBinder transferFrom, boolean createIfNeeded) {
3349 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3350 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003351 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 }
3353
3354 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003355 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3357 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003359 AppWindowToken wtoken = findAppWindowToken(token);
3360 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003361 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 return;
3363 }
3364
3365 // If the display is frozen, we won't do anything until the
3366 // actual window is displayed so there is no reason to put in
3367 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003368 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 return;
3370 }
Romain Guy06882f82009-06-10 13:36:04 -07003371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003372 if (wtoken.startingData != null) {
3373 return;
3374 }
Romain Guy06882f82009-06-10 13:36:04 -07003375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 if (transferFrom != null) {
3377 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3378 if (ttoken != null) {
3379 WindowState startingWindow = ttoken.startingWindow;
3380 if (startingWindow != null) {
3381 if (mStartingIconInTransition) {
3382 // In this case, the starting icon has already
3383 // been displayed, so start letting windows get
3384 // shown immediately without any more transitions.
3385 mSkipAppTransitionAnimation = true;
3386 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003387 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 "Moving existing starting from " + ttoken
3389 + " to " + wtoken);
3390 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 // Transfer the starting window over to the new
3393 // token.
3394 wtoken.startingData = ttoken.startingData;
3395 wtoken.startingView = ttoken.startingView;
3396 wtoken.startingWindow = startingWindow;
3397 ttoken.startingData = null;
3398 ttoken.startingView = null;
3399 ttoken.startingWindow = null;
3400 ttoken.startingMoved = true;
3401 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003402 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003404 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003405 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 mWindows.remove(startingWindow);
3407 ttoken.windows.remove(startingWindow);
3408 ttoken.allAppWindows.remove(startingWindow);
3409 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003411 // Propagate other interesting state between the
3412 // tokens. If the old token is displayed, we should
3413 // immediately force the new one to be displayed. If
3414 // it is animating, we need to move that animation to
3415 // the new one.
3416 if (ttoken.allDrawn) {
3417 wtoken.allDrawn = true;
3418 }
3419 if (ttoken.firstWindowDrawn) {
3420 wtoken.firstWindowDrawn = true;
3421 }
3422 if (!ttoken.hidden) {
3423 wtoken.hidden = false;
3424 wtoken.hiddenRequested = false;
3425 wtoken.willBeHidden = false;
3426 }
3427 if (wtoken.clientHidden != ttoken.clientHidden) {
3428 wtoken.clientHidden = ttoken.clientHidden;
3429 wtoken.sendAppVisibilityToClients();
3430 }
3431 if (ttoken.animation != null) {
3432 wtoken.animation = ttoken.animation;
3433 wtoken.animating = ttoken.animating;
3434 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3435 ttoken.animation = null;
3436 ttoken.animLayerAdjustment = 0;
3437 wtoken.updateLayers();
3438 ttoken.updateLayers();
3439 }
Romain Guy06882f82009-06-10 13:36:04 -07003440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 mLayoutNeeded = true;
3443 performLayoutAndPlaceSurfacesLocked();
3444 Binder.restoreCallingIdentity(origId);
3445 return;
3446 } else if (ttoken.startingData != null) {
3447 // The previous app was getting ready to show a
3448 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003449 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 "Moving pending starting from " + ttoken
3451 + " to " + wtoken);
3452 wtoken.startingData = ttoken.startingData;
3453 ttoken.startingData = null;
3454 ttoken.startingMoved = true;
3455 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3456 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3457 // want to process the message ASAP, before any other queued
3458 // messages.
3459 mH.sendMessageAtFrontOfQueue(m);
3460 return;
3461 }
3462 }
3463 }
3464
3465 // There is no existing starting window, and the caller doesn't
3466 // want us to create one, so that's it!
3467 if (!createIfNeeded) {
3468 return;
3469 }
Romain Guy06882f82009-06-10 13:36:04 -07003470
Dianne Hackborn284ac932009-08-28 10:34:25 -07003471 // If this is a translucent or wallpaper window, then don't
3472 // show a starting window -- the current effect (a full-screen
3473 // opaque starting window that fades away to the real contents
3474 // when it is ready) does not work for this.
3475 if (theme != 0) {
3476 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3477 com.android.internal.R.styleable.Window);
3478 if (ent.array.getBoolean(
3479 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3480 return;
3481 }
3482 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003483 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3484 return;
3485 }
3486 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003487 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3488 return;
3489 }
3490 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 mStartingIconInTransition = true;
3493 wtoken.startingData = new StartingData(
3494 pkg, theme, nonLocalizedLabel,
3495 labelRes, icon);
3496 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3497 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3498 // want to process the message ASAP, before any other queued
3499 // messages.
3500 mH.sendMessageAtFrontOfQueue(m);
3501 }
3502 }
3503
3504 public void setAppWillBeHidden(IBinder token) {
3505 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3506 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003507 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003508 }
3509
3510 AppWindowToken wtoken;
3511
3512 synchronized(mWindowMap) {
3513 wtoken = findAppWindowToken(token);
3514 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003515 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 -08003516 return;
3517 }
3518 wtoken.willBeHidden = true;
3519 }
3520 }
Romain Guy06882f82009-06-10 13:36:04 -07003521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3523 boolean visible, int transit, boolean performLayout) {
3524 boolean delayed = false;
3525
3526 if (wtoken.clientHidden == visible) {
3527 wtoken.clientHidden = !visible;
3528 wtoken.sendAppVisibilityToClients();
3529 }
Romain Guy06882f82009-06-10 13:36:04 -07003530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 wtoken.willBeHidden = false;
3532 if (wtoken.hidden == visible) {
3533 final int N = wtoken.allAppWindows.size();
3534 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003535 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3537 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003539 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003540
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003541 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 if (wtoken.animation == sDummyAnimation) {
3543 wtoken.animation = null;
3544 }
3545 applyAnimationLocked(wtoken, lp, transit, visible);
3546 changed = true;
3547 if (wtoken.animation != null) {
3548 delayed = runningAppAnimation = true;
3549 }
3550 }
Romain Guy06882f82009-06-10 13:36:04 -07003551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 for (int i=0; i<N; i++) {
3553 WindowState win = wtoken.allAppWindows.get(i);
3554 if (win == wtoken.startingWindow) {
3555 continue;
3556 }
3557
3558 if (win.isAnimating()) {
3559 delayed = true;
3560 }
Romain Guy06882f82009-06-10 13:36:04 -07003561
Joe Onorato8a9b2202010-02-26 18:56:32 -08003562 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 //win.dump(" ");
3564 if (visible) {
3565 if (!win.isVisibleNow()) {
3566 if (!runningAppAnimation) {
3567 applyAnimationLocked(win,
3568 WindowManagerPolicy.TRANSIT_ENTER, true);
3569 }
3570 changed = true;
3571 }
3572 } else if (win.isVisibleNow()) {
3573 if (!runningAppAnimation) {
3574 applyAnimationLocked(win,
3575 WindowManagerPolicy.TRANSIT_EXIT, false);
3576 }
3577 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3578 KeyWaiter.RETURN_NOTHING);
3579 changed = true;
3580 }
3581 }
3582
3583 wtoken.hidden = wtoken.hiddenRequested = !visible;
3584 if (!visible) {
3585 unsetAppFreezingScreenLocked(wtoken, true, true);
3586 } else {
3587 // If we are being set visible, and the starting window is
3588 // not yet displayed, then make sure it doesn't get displayed.
3589 WindowState swin = wtoken.startingWindow;
3590 if (swin != null && (swin.mDrawPending
3591 || swin.mCommitDrawPending)) {
3592 swin.mPolicyVisibility = false;
3593 swin.mPolicyVisibilityAfterAnim = false;
3594 }
3595 }
Romain Guy06882f82009-06-10 13:36:04 -07003596
Joe Onorato8a9b2202010-02-26 18:56:32 -08003597 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3599 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003600
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003601 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003603 if (performLayout) {
3604 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3605 performLayoutAndPlaceSurfacesLocked();
3606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 }
3608 }
3609
3610 if (wtoken.animation != null) {
3611 delayed = true;
3612 }
Romain Guy06882f82009-06-10 13:36:04 -07003613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 return delayed;
3615 }
3616
3617 public void setAppVisibility(IBinder token, boolean visible) {
3618 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3619 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003620 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 }
3622
3623 AppWindowToken wtoken;
3624
3625 synchronized(mWindowMap) {
3626 wtoken = findAppWindowToken(token);
3627 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003628 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 return;
3630 }
3631
3632 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003633 RuntimeException e = null;
3634 if (!HIDE_STACK_CRAWLS) {
3635 e = new RuntimeException();
3636 e.fillInStackTrace();
3637 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003638 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 + "): mNextAppTransition=" + mNextAppTransition
3640 + " hidden=" + wtoken.hidden
3641 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3642 }
Romain Guy06882f82009-06-10 13:36:04 -07003643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 // If we are preparing an app transition, then delay changing
3645 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003646 if (!mDisplayFrozen && mPolicy.isScreenOn()
3647 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003648 // Already in requested state, don't do anything more.
3649 if (wtoken.hiddenRequested != visible) {
3650 return;
3651 }
3652 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003653
Joe Onorato8a9b2202010-02-26 18:56:32 -08003654 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003655 TAG, "Setting dummy animation on: " + wtoken);
3656 wtoken.setDummyAnimation();
3657 mOpeningApps.remove(wtoken);
3658 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003659 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 wtoken.inPendingTransaction = true;
3661 if (visible) {
3662 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 wtoken.startingDisplayed = false;
3664 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003665
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003666 // If the token is currently hidden (should be the
3667 // common case), then we need to set up to wait for
3668 // its windows to be ready.
3669 if (wtoken.hidden) {
3670 wtoken.allDrawn = false;
3671 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003672
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003673 if (wtoken.clientHidden) {
3674 // In the case where we are making an app visible
3675 // but holding off for a transition, we still need
3676 // to tell the client to make its windows visible so
3677 // they get drawn. Otherwise, we will wait on
3678 // performing the transition until all windows have
3679 // been drawn, they never will be, and we are sad.
3680 wtoken.clientHidden = false;
3681 wtoken.sendAppVisibilityToClients();
3682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 }
3684 } else {
3685 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003686
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003687 // If the token is currently visible (should be the
3688 // common case), then set up to wait for it to be hidden.
3689 if (!wtoken.hidden) {
3690 wtoken.waitingToHide = true;
3691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 }
3693 return;
3694 }
Romain Guy06882f82009-06-10 13:36:04 -07003695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003697 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003698 wtoken.updateReportedVisibilityLocked();
3699 Binder.restoreCallingIdentity(origId);
3700 }
3701 }
3702
3703 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3704 boolean unfreezeSurfaceNow, boolean force) {
3705 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003706 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 + " force=" + force);
3708 final int N = wtoken.allAppWindows.size();
3709 boolean unfrozeWindows = false;
3710 for (int i=0; i<N; i++) {
3711 WindowState w = wtoken.allAppWindows.get(i);
3712 if (w.mAppFreezing) {
3713 w.mAppFreezing = false;
3714 if (w.mSurface != null && !w.mOrientationChanging) {
3715 w.mOrientationChanging = true;
3716 }
3717 unfrozeWindows = true;
3718 }
3719 }
3720 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003721 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 wtoken.freezingScreen = false;
3723 mAppsFreezingScreen--;
3724 }
3725 if (unfreezeSurfaceNow) {
3726 if (unfrozeWindows) {
3727 mLayoutNeeded = true;
3728 performLayoutAndPlaceSurfacesLocked();
3729 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003730 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 }
3732 }
3733 }
Romain Guy06882f82009-06-10 13:36:04 -07003734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3736 int configChanges) {
3737 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003738 RuntimeException e = null;
3739 if (!HIDE_STACK_CRAWLS) {
3740 e = new RuntimeException();
3741 e.fillInStackTrace();
3742 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003743 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 + ": hidden=" + wtoken.hidden + " freezing="
3745 + wtoken.freezingScreen, e);
3746 }
3747 if (!wtoken.hiddenRequested) {
3748 if (!wtoken.freezingScreen) {
3749 wtoken.freezingScreen = true;
3750 mAppsFreezingScreen++;
3751 if (mAppsFreezingScreen == 1) {
3752 startFreezingDisplayLocked();
3753 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3754 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3755 5000);
3756 }
3757 }
3758 final int N = wtoken.allAppWindows.size();
3759 for (int i=0; i<N; i++) {
3760 WindowState w = wtoken.allAppWindows.get(i);
3761 w.mAppFreezing = true;
3762 }
3763 }
3764 }
Romain Guy06882f82009-06-10 13:36:04 -07003765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 public void startAppFreezingScreen(IBinder token, int configChanges) {
3767 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3768 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003769 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 }
3771
3772 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003773 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003774 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003775 return;
3776 }
Romain Guy06882f82009-06-10 13:36:04 -07003777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003778 AppWindowToken wtoken = findAppWindowToken(token);
3779 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003780 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 return;
3782 }
3783 final long origId = Binder.clearCallingIdentity();
3784 startAppFreezingScreenLocked(wtoken, configChanges);
3785 Binder.restoreCallingIdentity(origId);
3786 }
3787 }
Romain Guy06882f82009-06-10 13:36:04 -07003788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003789 public void stopAppFreezingScreen(IBinder token, boolean force) {
3790 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3791 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003792 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 }
3794
3795 synchronized(mWindowMap) {
3796 AppWindowToken wtoken = findAppWindowToken(token);
3797 if (wtoken == null || wtoken.appToken == null) {
3798 return;
3799 }
3800 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003801 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3803 unsetAppFreezingScreenLocked(wtoken, true, force);
3804 Binder.restoreCallingIdentity(origId);
3805 }
3806 }
Romain Guy06882f82009-06-10 13:36:04 -07003807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 public void removeAppToken(IBinder token) {
3809 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3810 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003811 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 }
3813
3814 AppWindowToken wtoken = null;
3815 AppWindowToken startingToken = null;
3816 boolean delayed = false;
3817
3818 final long origId = Binder.clearCallingIdentity();
3819 synchronized(mWindowMap) {
3820 WindowToken basewtoken = mTokenMap.remove(token);
3821 mTokenList.remove(basewtoken);
3822 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003823 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003824 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 wtoken.inPendingTransaction = false;
3826 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003827 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 if (mClosingApps.contains(wtoken)) {
3829 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003830 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003832 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 delayed = true;
3834 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003835 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 TAG, "Removing app " + wtoken + " delayed=" + delayed
3837 + " animation=" + wtoken.animation
3838 + " animating=" + wtoken.animating);
3839 if (delayed) {
3840 // set the token aside because it has an active animation to be finished
3841 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003842 } else {
3843 // Make sure there is no animation running on this token,
3844 // so any windows associated with it will be removed as
3845 // soon as their animations are complete
3846 wtoken.animation = null;
3847 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003848 }
3849 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003850 if (mLastEnterAnimToken == wtoken) {
3851 mLastEnterAnimToken = null;
3852 mLastEnterAnimParams = null;
3853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 wtoken.removed = true;
3855 if (wtoken.startingData != null) {
3856 startingToken = wtoken;
3857 }
3858 unsetAppFreezingScreenLocked(wtoken, true, true);
3859 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003860 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003861 mFocusedApp = null;
3862 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3863 mKeyWaiter.tickle();
3864 }
3865 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003866 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 }
Romain Guy06882f82009-06-10 13:36:04 -07003868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 if (!delayed && wtoken != null) {
3870 wtoken.updateReportedVisibilityLocked();
3871 }
3872 }
3873 Binder.restoreCallingIdentity(origId);
3874
3875 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003876 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 + startingToken + ": app token removed");
3878 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3879 mH.sendMessage(m);
3880 }
3881 }
3882
3883 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3884 final int NW = token.windows.size();
3885 for (int i=0; i<NW; i++) {
3886 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003887 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 mWindows.remove(win);
3889 int j = win.mChildWindows.size();
3890 while (j > 0) {
3891 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003892 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003893 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003894 "Tmp removing child window " + cwin);
3895 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 }
3897 }
3898 return NW > 0;
3899 }
3900
3901 void dumpAppTokensLocked() {
3902 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003903 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
3905 }
Romain Guy06882f82009-06-10 13:36:04 -07003906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 void dumpWindowsLocked() {
3908 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003909 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 }
3911 }
Romain Guy06882f82009-06-10 13:36:04 -07003912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 private int findWindowOffsetLocked(int tokenPos) {
3914 final int NW = mWindows.size();
3915
3916 if (tokenPos >= mAppTokens.size()) {
3917 int i = NW;
3918 while (i > 0) {
3919 i--;
3920 WindowState win = (WindowState)mWindows.get(i);
3921 if (win.getAppToken() != null) {
3922 return i+1;
3923 }
3924 }
3925 }
3926
3927 while (tokenPos > 0) {
3928 // Find the first app token below the new position that has
3929 // a window displayed.
3930 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003931 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003933 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07003935 "Skipping token -- currently sending to bottom");
3936 tokenPos--;
3937 continue;
3938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 int i = wtoken.windows.size();
3940 while (i > 0) {
3941 i--;
3942 WindowState win = wtoken.windows.get(i);
3943 int j = win.mChildWindows.size();
3944 while (j > 0) {
3945 j--;
3946 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003947 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 for (int pos=NW-1; pos>=0; pos--) {
3949 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003950 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 "Found child win @" + (pos+1));
3952 return pos+1;
3953 }
3954 }
3955 }
3956 }
3957 for (int pos=NW-1; pos>=0; pos--) {
3958 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003959 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 return pos+1;
3961 }
3962 }
3963 }
3964 tokenPos--;
3965 }
3966
3967 return 0;
3968 }
3969
3970 private final int reAddWindowLocked(int index, WindowState win) {
3971 final int NCW = win.mChildWindows.size();
3972 boolean added = false;
3973 for (int j=0; j<NCW; j++) {
3974 WindowState cwin = (WindowState)win.mChildWindows.get(j);
3975 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003976 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003977 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 mWindows.add(index, win);
3979 index++;
3980 added = true;
3981 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003982 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003983 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 mWindows.add(index, cwin);
3985 index++;
3986 }
3987 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003988 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003989 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 mWindows.add(index, win);
3991 index++;
3992 }
3993 return index;
3994 }
Romain Guy06882f82009-06-10 13:36:04 -07003995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 private final int reAddAppWindowsLocked(int index, WindowToken token) {
3997 final int NW = token.windows.size();
3998 for (int i=0; i<NW; i++) {
3999 index = reAddWindowLocked(index, token.windows.get(i));
4000 }
4001 return index;
4002 }
4003
4004 public void moveAppToken(int index, IBinder token) {
4005 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4006 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004007 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004008 }
4009
4010 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004011 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 if (DEBUG_REORDER) dumpAppTokensLocked();
4013 final AppWindowToken wtoken = findAppWindowToken(token);
4014 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004015 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 + token + " (" + wtoken + ")");
4017 return;
4018 }
4019 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004020 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004024 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 if (DEBUG_REORDER) dumpWindowsLocked();
4026 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004027 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 if (DEBUG_REORDER) dumpWindowsLocked();
4029 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004030 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 if (DEBUG_REORDER) dumpWindowsLocked();
4032 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 mLayoutNeeded = true;
4034 performLayoutAndPlaceSurfacesLocked();
4035 }
4036 Binder.restoreCallingIdentity(origId);
4037 }
4038 }
4039
4040 private void removeAppTokensLocked(List<IBinder> tokens) {
4041 // XXX This should be done more efficiently!
4042 // (take advantage of the fact that both lists should be
4043 // ordered in the same way.)
4044 int N = tokens.size();
4045 for (int i=0; i<N; i++) {
4046 IBinder token = tokens.get(i);
4047 final AppWindowToken wtoken = findAppWindowToken(token);
4048 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004049 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004050 + token + " (" + wtoken + ")");
4051 i--;
4052 N--;
4053 }
4054 }
4055 }
4056
Dianne Hackborna8f60182009-09-01 19:01:50 -07004057 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4058 boolean updateFocusAndLayout) {
4059 // First remove all of the windows from the list.
4060 tmpRemoveAppWindowsLocked(wtoken);
4061
4062 // Where to start adding?
4063 int pos = findWindowOffsetLocked(tokenPos);
4064
4065 // And now add them back at the correct place.
4066 pos = reAddAppWindowsLocked(pos, wtoken);
4067
4068 if (updateFocusAndLayout) {
4069 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4070 assignLayersLocked();
4071 }
4072 mLayoutNeeded = true;
4073 performLayoutAndPlaceSurfacesLocked();
4074 }
4075 }
4076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4078 // First remove all of the windows from the list.
4079 final int N = tokens.size();
4080 int i;
4081 for (i=0; i<N; i++) {
4082 WindowToken token = mTokenMap.get(tokens.get(i));
4083 if (token != null) {
4084 tmpRemoveAppWindowsLocked(token);
4085 }
4086 }
4087
4088 // Where to start adding?
4089 int pos = findWindowOffsetLocked(tokenPos);
4090
4091 // And now add them back at the correct place.
4092 for (i=0; i<N; i++) {
4093 WindowToken token = mTokenMap.get(tokens.get(i));
4094 if (token != null) {
4095 pos = reAddAppWindowsLocked(pos, token);
4096 }
4097 }
4098
Dianne Hackborna8f60182009-09-01 19:01:50 -07004099 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4100 assignLayersLocked();
4101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 mLayoutNeeded = true;
4103 performLayoutAndPlaceSurfacesLocked();
4104
4105 //dump();
4106 }
4107
4108 public void moveAppTokensToTop(List<IBinder> tokens) {
4109 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4110 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004111 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 }
4113
4114 final long origId = Binder.clearCallingIdentity();
4115 synchronized(mWindowMap) {
4116 removeAppTokensLocked(tokens);
4117 final int N = tokens.size();
4118 for (int i=0; i<N; i++) {
4119 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4120 if (wt != null) {
4121 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004122 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004123 mToTopApps.remove(wt);
4124 mToBottomApps.remove(wt);
4125 mToTopApps.add(wt);
4126 wt.sendingToBottom = false;
4127 wt.sendingToTop = true;
4128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004129 }
4130 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004131
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004132 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004133 moveAppWindowsLocked(tokens, mAppTokens.size());
4134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 }
4136 Binder.restoreCallingIdentity(origId);
4137 }
4138
4139 public void moveAppTokensToBottom(List<IBinder> tokens) {
4140 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4141 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004142 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 }
4144
4145 final long origId = Binder.clearCallingIdentity();
4146 synchronized(mWindowMap) {
4147 removeAppTokensLocked(tokens);
4148 final int N = tokens.size();
4149 int pos = 0;
4150 for (int i=0; i<N; i++) {
4151 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4152 if (wt != null) {
4153 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004154 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004155 mToTopApps.remove(wt);
4156 mToBottomApps.remove(wt);
4157 mToBottomApps.add(i, wt);
4158 wt.sendingToTop = false;
4159 wt.sendingToBottom = true;
4160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 pos++;
4162 }
4163 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004164
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004165 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004166 moveAppWindowsLocked(tokens, 0);
4167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 }
4169 Binder.restoreCallingIdentity(origId);
4170 }
4171
4172 // -------------------------------------------------------------
4173 // Misc IWindowSession methods
4174 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004175
Jim Millerd6b57052010-06-07 17:52:42 -07004176 private boolean allowDisableKeyguard()
4177 {
4178 // We fail safe if this gets called before the service has started.
4179 boolean allow = false;
4180 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4181 Context.DEVICE_POLICY_SERVICE);
4182 if (dpm != null) {
4183 allow = dpm.getPasswordQuality(null)
4184 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
4185 }
4186 return allow;
4187 }
4188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004190 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 != PackageManager.PERMISSION_GRANTED) {
4192 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4193 }
Jim Millerd6b57052010-06-07 17:52:42 -07004194
4195 if (allowDisableKeyguard()) {
4196 synchronized (mKeyguardTokenWatcher) {
4197 mKeyguardTokenWatcher.acquire(token, tag);
4198 }
4199 } else {
4200 Log.w(TAG, tag + ": disableKeyguard() ignored while DevicePolicyAmin is enabled.");
Mike Lockwooddd884682009-10-11 16:57:08 -04004201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004202 }
4203
4204 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004205 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 != PackageManager.PERMISSION_GRANTED) {
4207 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209
Jim Millerd6b57052010-06-07 17:52:42 -07004210 if (allowDisableKeyguard()) {
4211 synchronized (mKeyguardTokenWatcher) {
4212 mKeyguardTokenWatcher.release(token);
4213
4214 if (!mKeyguardTokenWatcher.isAcquired()) {
4215 // If we are the last one to reenable the keyguard wait until
4216 // we have actaully finished reenabling until returning.
4217 // It is possible that reenableKeyguard() can be called before
4218 // the previous disableKeyguard() is handled, in which case
4219 // neither mKeyguardTokenWatcher.acquired() or released() would
4220 // be called. In that case mKeyguardDisabled will be false here
4221 // and we have nothing to wait for.
4222 while (mKeyguardDisabled) {
4223 try {
4224 mKeyguardTokenWatcher.wait();
4225 } catch (InterruptedException e) {
4226 Thread.currentThread().interrupt();
4227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 }
4229 }
4230 }
Jim Millerd6b57052010-06-07 17:52:42 -07004231 } else {
4232 Log.w(TAG, "reenableKeyguard() ignored while DevicePolicyAmin is enabled.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 }
4234 }
4235
4236 /**
4237 * @see android.app.KeyguardManager#exitKeyguardSecurely
4238 */
4239 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004240 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 != PackageManager.PERMISSION_GRANTED) {
4242 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4243 }
4244 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4245 public void onKeyguardExitResult(boolean success) {
4246 try {
4247 callback.onKeyguardExitResult(success);
4248 } catch (RemoteException e) {
4249 // Client has died, we don't care.
4250 }
4251 }
4252 });
4253 }
4254
4255 public boolean inKeyguardRestrictedInputMode() {
4256 return mPolicy.inKeyguardRestrictedKeyInputMode();
4257 }
Romain Guy06882f82009-06-10 13:36:04 -07004258
Dianne Hackbornffa42482009-09-23 22:20:11 -07004259 public void closeSystemDialogs(String reason) {
4260 synchronized(mWindowMap) {
4261 for (int i=mWindows.size()-1; i>=0; i--) {
4262 WindowState w = (WindowState)mWindows.get(i);
4263 if (w.mSurface != null) {
4264 try {
4265 w.mClient.closeSystemDialogs(reason);
4266 } catch (RemoteException e) {
4267 }
4268 }
4269 }
4270 }
4271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 static float fixScale(float scale) {
4274 if (scale < 0) scale = 0;
4275 else if (scale > 20) scale = 20;
4276 return Math.abs(scale);
4277 }
Romain Guy06882f82009-06-10 13:36:04 -07004278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 public void setAnimationScale(int which, float scale) {
4280 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4281 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004282 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 }
4284
4285 if (scale < 0) scale = 0;
4286 else if (scale > 20) scale = 20;
4287 scale = Math.abs(scale);
4288 switch (which) {
4289 case 0: mWindowAnimationScale = fixScale(scale); break;
4290 case 1: mTransitionAnimationScale = fixScale(scale); break;
4291 }
Romain Guy06882f82009-06-10 13:36:04 -07004292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 // Persist setting
4294 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4295 }
Romain Guy06882f82009-06-10 13:36:04 -07004296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 public void setAnimationScales(float[] scales) {
4298 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4299 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004300 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 }
4302
4303 if (scales != null) {
4304 if (scales.length >= 1) {
4305 mWindowAnimationScale = fixScale(scales[0]);
4306 }
4307 if (scales.length >= 2) {
4308 mTransitionAnimationScale = fixScale(scales[1]);
4309 }
4310 }
Romain Guy06882f82009-06-10 13:36:04 -07004311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 // Persist setting
4313 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4314 }
Romain Guy06882f82009-06-10 13:36:04 -07004315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 public float getAnimationScale(int which) {
4317 switch (which) {
4318 case 0: return mWindowAnimationScale;
4319 case 1: return mTransitionAnimationScale;
4320 }
4321 return 0;
4322 }
Romain Guy06882f82009-06-10 13:36:04 -07004323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 public float[] getAnimationScales() {
4325 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4326 }
Romain Guy06882f82009-06-10 13:36:04 -07004327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004328 public int getSwitchState(int sw) {
4329 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4330 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004331 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 }
4333 return KeyInputQueue.getSwitchState(sw);
4334 }
Romain Guy06882f82009-06-10 13:36:04 -07004335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 public int getSwitchStateForDevice(int devid, int sw) {
4337 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4338 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004339 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 }
4341 return KeyInputQueue.getSwitchState(devid, sw);
4342 }
Romain Guy06882f82009-06-10 13:36:04 -07004343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004344 public int getScancodeState(int sw) {
4345 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4346 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004347 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 }
Dianne Hackborn6af0d502009-09-28 13:25:46 -07004349 return mQueue.getScancodeState(sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 }
Romain Guy06882f82009-06-10 13:36:04 -07004351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 public int getScancodeStateForDevice(int devid, int sw) {
4353 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4354 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004355 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 }
Dianne Hackborn6af0d502009-09-28 13:25:46 -07004357 return mQueue.getScancodeState(devid, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 }
Romain Guy06882f82009-06-10 13:36:04 -07004359
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004360 public int getTrackballScancodeState(int sw) {
4361 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4362 "getTrackballScancodeState()")) {
4363 throw new SecurityException("Requires READ_INPUT_STATE permission");
4364 }
4365 return mQueue.getTrackballScancodeState(sw);
4366 }
4367
4368 public int getDPadScancodeState(int sw) {
4369 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4370 "getDPadScancodeState()")) {
4371 throw new SecurityException("Requires READ_INPUT_STATE permission");
4372 }
4373 return mQueue.getDPadScancodeState(sw);
4374 }
4375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 public int getKeycodeState(int sw) {
4377 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4378 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004379 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 }
Dianne Hackborn6af0d502009-09-28 13:25:46 -07004381 return mQueue.getKeycodeState(sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 }
Romain Guy06882f82009-06-10 13:36:04 -07004383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 public int getKeycodeStateForDevice(int devid, int sw) {
4385 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4386 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004387 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 }
Dianne Hackborn6af0d502009-09-28 13:25:46 -07004389 return mQueue.getKeycodeState(devid, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
Romain Guy06882f82009-06-10 13:36:04 -07004391
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004392 public int getTrackballKeycodeState(int sw) {
4393 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4394 "getTrackballKeycodeState()")) {
4395 throw new SecurityException("Requires READ_INPUT_STATE permission");
4396 }
4397 return mQueue.getTrackballKeycodeState(sw);
4398 }
4399
4400 public int getDPadKeycodeState(int sw) {
4401 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4402 "getDPadKeycodeState()")) {
4403 throw new SecurityException("Requires READ_INPUT_STATE permission");
4404 }
4405 return mQueue.getDPadKeycodeState(sw);
4406 }
4407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
4409 return KeyInputQueue.hasKeys(keycodes, keyExists);
4410 }
Romain Guy06882f82009-06-10 13:36:04 -07004411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 public void enableScreenAfterBoot() {
4413 synchronized(mWindowMap) {
4414 if (mSystemBooted) {
4415 return;
4416 }
4417 mSystemBooted = true;
4418 }
Romain Guy06882f82009-06-10 13:36:04 -07004419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 performEnableScreen();
4421 }
Romain Guy06882f82009-06-10 13:36:04 -07004422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 public void enableScreenIfNeededLocked() {
4424 if (mDisplayEnabled) {
4425 return;
4426 }
4427 if (!mSystemBooted) {
4428 return;
4429 }
4430 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4431 }
Romain Guy06882f82009-06-10 13:36:04 -07004432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 public void performEnableScreen() {
4434 synchronized(mWindowMap) {
4435 if (mDisplayEnabled) {
4436 return;
4437 }
4438 if (!mSystemBooted) {
4439 return;
4440 }
Romain Guy06882f82009-06-10 13:36:04 -07004441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 // Don't enable the screen until all existing windows
4443 // have been drawn.
4444 final int N = mWindows.size();
4445 for (int i=0; i<N; i++) {
4446 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn5943c202010-04-12 21:36:49 -07004447 if (w.isVisibleLw() && !w.mObscured
4448 && (w.mOrientationChanging || !w.isDrawnLw())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 return;
4450 }
4451 }
Romain Guy06882f82009-06-10 13:36:04 -07004452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 mDisplayEnabled = true;
4454 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004455 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 StringWriter sw = new StringWriter();
4457 PrintWriter pw = new PrintWriter(sw);
4458 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004459 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 }
4461 try {
4462 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4463 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004464 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 Parcel data = Parcel.obtain();
4466 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4467 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4468 data, null, 0);
4469 data.recycle();
4470 }
4471 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004472 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 }
4474 }
Romain Guy06882f82009-06-10 13:36:04 -07004475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004479 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4480 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
Romain Guy06882f82009-06-10 13:36:04 -07004482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004483 public void setInTouchMode(boolean mode) {
4484 synchronized(mWindowMap) {
4485 mInTouchMode = mode;
4486 }
4487 }
4488
Romain Guy06882f82009-06-10 13:36:04 -07004489 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004490 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004492 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004493 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 }
4495
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004496 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 }
Romain Guy06882f82009-06-10 13:36:04 -07004498
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004499 public void setRotationUnchecked(int rotation,
4500 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004501 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 long origId = Binder.clearCallingIdentity();
4505 boolean changed;
4506 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004507 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 }
Romain Guy06882f82009-06-10 13:36:04 -07004509
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004510 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 sendNewConfiguration();
4512 }
Romain Guy06882f82009-06-10 13:36:04 -07004513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 Binder.restoreCallingIdentity(origId);
4515 }
Romain Guy06882f82009-06-10 13:36:04 -07004516
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004517 /**
4518 * Apply a new rotation to the screen, respecting the requests of
4519 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4520 * re-evaluate the desired rotation.
4521 *
4522 * Returns null if the rotation has been changed. In this case YOU
4523 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4524 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004525 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 boolean changed;
4527 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4528 rotation = mRequestedRotation;
4529 } else {
4530 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004531 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004533 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004534 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004536 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004540 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 "Rotation changed to " + rotation
4542 + " from " + mRotation
4543 + " (forceApp=" + mForcedAppOrientation
4544 + ", req=" + mRequestedRotation + ")");
4545 mRotation = rotation;
4546 mWindowsFreezingScreen = true;
4547 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4548 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4549 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004550 mWaitingForConfig = true;
4551 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004553 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 mQueue.setOrientation(rotation);
4555 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004556 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 }
4558 for (int i=mWindows.size()-1; i>=0; i--) {
4559 WindowState w = (WindowState)mWindows.get(i);
4560 if (w.mSurface != null) {
4561 w.mOrientationChanging = true;
4562 }
4563 }
4564 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4565 try {
4566 mRotationWatchers.get(i).onRotationChanged(rotation);
4567 } catch (RemoteException e) {
4568 }
4569 }
4570 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 return changed;
4573 }
Romain Guy06882f82009-06-10 13:36:04 -07004574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 public int getRotation() {
4576 return mRotation;
4577 }
4578
4579 public int watchRotation(IRotationWatcher watcher) {
4580 final IBinder watcherBinder = watcher.asBinder();
4581 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4582 public void binderDied() {
4583 synchronized (mWindowMap) {
4584 for (int i=0; i<mRotationWatchers.size(); i++) {
4585 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004586 IRotationWatcher removed = mRotationWatchers.remove(i);
4587 if (removed != null) {
4588 removed.asBinder().unlinkToDeath(this, 0);
4589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 i--;
4591 }
4592 }
4593 }
4594 }
4595 };
Romain Guy06882f82009-06-10 13:36:04 -07004596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 synchronized (mWindowMap) {
4598 try {
4599 watcher.asBinder().linkToDeath(dr, 0);
4600 mRotationWatchers.add(watcher);
4601 } catch (RemoteException e) {
4602 // Client died, no cleanup needed.
4603 }
Romain Guy06882f82009-06-10 13:36:04 -07004604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 return mRotation;
4606 }
4607 }
4608
4609 /**
4610 * Starts the view server on the specified port.
4611 *
4612 * @param port The port to listener to.
4613 *
4614 * @return True if the server was successfully started, false otherwise.
4615 *
4616 * @see com.android.server.ViewServer
4617 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4618 */
4619 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004620 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 return false;
4622 }
4623
4624 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4625 return false;
4626 }
4627
4628 if (port < 1024) {
4629 return false;
4630 }
4631
4632 if (mViewServer != null) {
4633 if (!mViewServer.isRunning()) {
4634 try {
4635 return mViewServer.start();
4636 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004637 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 }
4639 }
4640 return false;
4641 }
4642
4643 try {
4644 mViewServer = new ViewServer(this, port);
4645 return mViewServer.start();
4646 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004647 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 }
4649 return false;
4650 }
4651
Romain Guy06882f82009-06-10 13:36:04 -07004652 private boolean isSystemSecure() {
4653 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4654 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4655 }
4656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 /**
4658 * Stops the view server if it exists.
4659 *
4660 * @return True if the server stopped, false if it wasn't started or
4661 * couldn't be stopped.
4662 *
4663 * @see com.android.server.ViewServer
4664 */
4665 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004666 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 return false;
4668 }
4669
4670 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4671 return false;
4672 }
4673
4674 if (mViewServer != null) {
4675 return mViewServer.stop();
4676 }
4677 return false;
4678 }
4679
4680 /**
4681 * Indicates whether the view server is running.
4682 *
4683 * @return True if the server is running, false otherwise.
4684 *
4685 * @see com.android.server.ViewServer
4686 */
4687 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004688 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 return false;
4690 }
4691
4692 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4693 return false;
4694 }
4695
4696 return mViewServer != null && mViewServer.isRunning();
4697 }
4698
4699 /**
4700 * Lists all availble windows in the system. The listing is written in the
4701 * specified Socket's output stream with the following syntax:
4702 * windowHashCodeInHexadecimal windowName
4703 * Each line of the ouput represents a different window.
4704 *
4705 * @param client The remote client to send the listing to.
4706 * @return False if an error occured, true otherwise.
4707 */
4708 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004709 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 return false;
4711 }
4712
4713 boolean result = true;
4714
4715 Object[] windows;
4716 synchronized (mWindowMap) {
4717 windows = new Object[mWindows.size()];
4718 //noinspection unchecked
4719 windows = mWindows.toArray(windows);
4720 }
4721
4722 BufferedWriter out = null;
4723
4724 // Any uncaught exception will crash the system process
4725 try {
4726 OutputStream clientStream = client.getOutputStream();
4727 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4728
4729 final int count = windows.length;
4730 for (int i = 0; i < count; i++) {
4731 final WindowState w = (WindowState) windows[i];
4732 out.write(Integer.toHexString(System.identityHashCode(w)));
4733 out.write(' ');
4734 out.append(w.mAttrs.getTitle());
4735 out.write('\n');
4736 }
4737
4738 out.write("DONE.\n");
4739 out.flush();
4740 } catch (Exception e) {
4741 result = false;
4742 } finally {
4743 if (out != null) {
4744 try {
4745 out.close();
4746 } catch (IOException e) {
4747 result = false;
4748 }
4749 }
4750 }
4751
4752 return result;
4753 }
4754
4755 /**
4756 * Sends a command to a target window. The result of the command, if any, will be
4757 * written in the output stream of the specified socket.
4758 *
4759 * The parameters must follow this syntax:
4760 * windowHashcode extra
4761 *
4762 * Where XX is the length in characeters of the windowTitle.
4763 *
4764 * The first parameter is the target window. The window with the specified hashcode
4765 * will be the target. If no target can be found, nothing happens. The extra parameters
4766 * will be delivered to the target window and as parameters to the command itself.
4767 *
4768 * @param client The remote client to sent the result, if any, to.
4769 * @param command The command to execute.
4770 * @param parameters The command parameters.
4771 *
4772 * @return True if the command was successfully delivered, false otherwise. This does
4773 * not indicate whether the command itself was successful.
4774 */
4775 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004776 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004777 return false;
4778 }
4779
4780 boolean success = true;
4781 Parcel data = null;
4782 Parcel reply = null;
4783
4784 // Any uncaught exception will crash the system process
4785 try {
4786 // Find the hashcode of the window
4787 int index = parameters.indexOf(' ');
4788 if (index == -1) {
4789 index = parameters.length();
4790 }
4791 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004792 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793
4794 // Extract the command's parameter after the window description
4795 if (index < parameters.length()) {
4796 parameters = parameters.substring(index + 1);
4797 } else {
4798 parameters = "";
4799 }
4800
4801 final WindowManagerService.WindowState window = findWindow(hashCode);
4802 if (window == null) {
4803 return false;
4804 }
4805
4806 data = Parcel.obtain();
4807 data.writeInterfaceToken("android.view.IWindow");
4808 data.writeString(command);
4809 data.writeString(parameters);
4810 data.writeInt(1);
4811 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4812
4813 reply = Parcel.obtain();
4814
4815 final IBinder binder = window.mClient.asBinder();
4816 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4817 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4818
4819 reply.readException();
4820
4821 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004822 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 success = false;
4824 } finally {
4825 if (data != null) {
4826 data.recycle();
4827 }
4828 if (reply != null) {
4829 reply.recycle();
4830 }
4831 }
4832
4833 return success;
4834 }
4835
4836 private WindowState findWindow(int hashCode) {
4837 if (hashCode == -1) {
4838 return getFocusedWindow();
4839 }
4840
4841 synchronized (mWindowMap) {
4842 final ArrayList windows = mWindows;
4843 final int count = windows.size();
4844
4845 for (int i = 0; i < count; i++) {
4846 WindowState w = (WindowState) windows.get(i);
4847 if (System.identityHashCode(w) == hashCode) {
4848 return w;
4849 }
4850 }
4851 }
4852
4853 return null;
4854 }
4855
4856 /*
4857 * Instruct the Activity Manager to fetch the current configuration and broadcast
4858 * that to config-changed listeners if appropriate.
4859 */
4860 void sendNewConfiguration() {
4861 try {
4862 mActivityManager.updateConfiguration(null);
4863 } catch (RemoteException e) {
4864 }
4865 }
Romain Guy06882f82009-06-10 13:36:04 -07004866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 public Configuration computeNewConfiguration() {
4868 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07004869 return computeNewConfigurationLocked();
4870 }
4871 }
Romain Guy06882f82009-06-10 13:36:04 -07004872
Dianne Hackbornc485a602009-03-24 22:39:49 -07004873 Configuration computeNewConfigurationLocked() {
4874 Configuration config = new Configuration();
4875 if (!computeNewConfigurationLocked(config)) {
4876 return null;
4877 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07004878 return config;
4879 }
Romain Guy06882f82009-06-10 13:36:04 -07004880
Dianne Hackbornc485a602009-03-24 22:39:49 -07004881 boolean computeNewConfigurationLocked(Configuration config) {
4882 if (mDisplay == null) {
4883 return false;
4884 }
4885 mQueue.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07004886
4887 // Use the effective "visual" dimensions based on current rotation
4888 final boolean rotated = (mRotation == Surface.ROTATION_90
4889 || mRotation == Surface.ROTATION_270);
4890 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
4891 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
4892
Dianne Hackbornc485a602009-03-24 22:39:49 -07004893 int orientation = Configuration.ORIENTATION_SQUARE;
4894 if (dw < dh) {
4895 orientation = Configuration.ORIENTATION_PORTRAIT;
4896 } else if (dw > dh) {
4897 orientation = Configuration.ORIENTATION_LANDSCAPE;
4898 }
4899 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004900
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07004901 DisplayMetrics dm = new DisplayMetrics();
4902 mDisplay.getMetrics(dm);
4903 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
4904
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004905 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07004906 // Note we only do this once because at this point we don't
4907 // expect the screen to change in this way at runtime, and want
4908 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07004909 int longSize = dw;
4910 int shortSize = dh;
4911 if (longSize < shortSize) {
4912 int tmp = longSize;
4913 longSize = shortSize;
4914 shortSize = tmp;
4915 }
4916 longSize = (int)(longSize/dm.density);
4917 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07004918
Dianne Hackborn723738c2009-06-25 19:48:04 -07004919 // These semi-magic numbers define our compatibility modes for
4920 // applications with different screens. Don't change unless you
4921 // make sure to test lots and lots of apps!
4922 if (longSize < 470) {
4923 // This is shorter than an HVGA normal density screen (which
4924 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004925 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
4926 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07004927 } else {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004928 // Is this a large screen?
4929 if (longSize > 640 && shortSize >= 480) {
4930 // VGA or larger screens at medium density are the point
4931 // at which we consider it to be a large screen.
4932 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
4933 } else {
4934 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004935
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004936 // If this screen is wider than normal HVGA, or taller
4937 // than FWVGA, then for old apps we want to run in size
4938 // compatibility mode.
4939 if (shortSize > 321 || longSize > 570) {
4940 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
4941 }
4942 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004943
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004944 // Is this a long screen?
4945 if (((longSize*3)/5) >= (shortSize-1)) {
4946 // Anything wider than WVGA (5:3) is considering to be long.
4947 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
4948 } else {
4949 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
4950 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07004951 }
4952 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07004953 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004954
Dianne Hackbornc485a602009-03-24 22:39:49 -07004955 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
4956 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
4957 mPolicy.adjustConfigurationLw(config);
4958 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 }
Romain Guy06882f82009-06-10 13:36:04 -07004960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004961 // -------------------------------------------------------------
4962 // Input Events and Focus Management
4963 // -------------------------------------------------------------
4964
4965 private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
Michael Chane96440f2009-05-06 10:27:36 -07004966 long curTime = SystemClock.uptimeMillis();
4967
Michael Chane10de972009-05-18 11:24:50 -07004968 if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
Michael Chane96440f2009-05-06 10:27:36 -07004969 if (mLastTouchEventType == eventType &&
4970 (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
4971 return;
4972 }
4973 mLastUserActivityCallTime = curTime;
4974 mLastTouchEventType = eventType;
4975 }
4976
4977 if (targetWin == null
4978 || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
4979 mPowerManager.userActivity(curTime, false, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 }
4981 }
4982
4983 // tells if it's a cheek event or not -- this function is stateful
4984 private static final int EVENT_NONE = 0;
4985 private static final int EVENT_UNKNOWN = 0;
4986 private static final int EVENT_CHEEK = 0;
4987 private static final int EVENT_IGNORE_DURATION = 300; // ms
4988 private static final float CHEEK_THRESHOLD = 0.6f;
4989 private int mEventState = EVENT_NONE;
4990 private float mEventSize;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07004991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992 private int eventType(MotionEvent ev) {
4993 float size = ev.getSize();
4994 switch (ev.getAction()) {
4995 case MotionEvent.ACTION_DOWN:
4996 mEventSize = size;
4997 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
4998 case MotionEvent.ACTION_UP:
4999 if (size > mEventSize) mEventSize = size;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005000 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 case MotionEvent.ACTION_MOVE:
5002 final int N = ev.getHistorySize();
5003 if (size > mEventSize) mEventSize = size;
5004 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5005 for (int i=0; i<N; i++) {
5006 size = ev.getHistoricalSize(i);
5007 if (size > mEventSize) mEventSize = size;
5008 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5009 }
5010 if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
5011 return TOUCH_EVENT;
5012 } else {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005013 return LONG_TOUCH_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005014 }
5015 default:
5016 // not good
5017 return OTHER_EVENT;
5018 }
5019 }
5020
5021 /**
5022 * @return Returns true if event was dispatched, false if it was dropped for any reason
5023 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005024 private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005025 if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 "dispatchPointer " + ev);
5027
Michael Chan53071d62009-05-13 17:29:48 -07005028 if (MEASURE_LATENCY) {
5029 lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
5030 }
5031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032 Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005033 ev, true, false, pid, uid);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005034
Michael Chan53071d62009-05-13 17:29:48 -07005035 if (MEASURE_LATENCY) {
5036 lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
5037 }
5038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 int action = ev.getAction();
Romain Guy06882f82009-06-10 13:36:04 -07005040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 if (action == MotionEvent.ACTION_UP) {
5042 // let go of our target
5043 mKeyWaiter.mMotionTarget = null;
5044 mPowerManager.logPointerUpEvent();
5045 } else if (action == MotionEvent.ACTION_DOWN) {
5046 mPowerManager.logPointerDownEvent();
5047 }
5048
5049 if (targetObj == null) {
5050 // In this case we are either dropping the event, or have received
5051 // a move or up without a down. It is common to receive move
5052 // events in such a way, since this means the user is moving the
5053 // pointer without actually pressing down. All other cases should
5054 // be atypical, so let's log them.
Michael Chane96440f2009-05-06 10:27:36 -07005055 if (action != MotionEvent.ACTION_MOVE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005056 Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005057 }
Dianne Hackborn6adba242009-11-10 11:10:09 -08005058 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005059 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005061 if (qev != null) {
5062 mQueue.recycleEvent(qev);
5063 }
5064 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005065 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 }
5067 if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005068 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005069 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 if (qev != null) {
5072 mQueue.recycleEvent(qev);
5073 }
5074 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005075 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 }
Romain Guy06882f82009-06-10 13:36:04 -07005077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 WindowState target = (WindowState)targetObj;
Romain Guy06882f82009-06-10 13:36:04 -07005079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 final long eventTime = ev.getEventTime();
Michael Chan53071d62009-05-13 17:29:48 -07005081 final long eventTimeNano = ev.getEventTimeNano();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005082
Joe Onorato8a9b2202010-02-26 18:56:32 -08005083 //Slog.i(TAG, "Sending " + ev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084
5085 if (uid != 0 && uid != target.mSession.mUid) {
5086 if (mContext.checkPermission(
5087 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5088 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005089 Slog.w(TAG, "Permission denied: injecting pointer event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005090 + pid + " uid " + uid + " to window " + target
5091 + " owned by uid " + target.mSession.mUid);
5092 if (qev != null) {
5093 mQueue.recycleEvent(qev);
5094 }
5095 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005096 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005097 }
5098 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005099
Michael Chan53071d62009-05-13 17:29:48 -07005100 if (MEASURE_LATENCY) {
5101 lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5102 }
5103
Romain Guy06882f82009-06-10 13:36:04 -07005104 if ((target.mAttrs.flags &
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5106 //target wants to ignore fat touch events
5107 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
5108 //explicit flag to return without processing event further
5109 boolean returnFlag = false;
5110 if((action == MotionEvent.ACTION_DOWN)) {
5111 mFatTouch = false;
5112 if(cheekPress) {
5113 mFatTouch = true;
5114 returnFlag = true;
5115 }
5116 } else {
5117 if(action == MotionEvent.ACTION_UP) {
5118 if(mFatTouch) {
5119 //earlier even was invalid doesnt matter if current up is cheekpress or not
5120 mFatTouch = false;
5121 returnFlag = true;
5122 } else if(cheekPress) {
5123 //cancel the earlier event
5124 ev.setAction(MotionEvent.ACTION_CANCEL);
5125 action = MotionEvent.ACTION_CANCEL;
5126 }
5127 } else if(action == MotionEvent.ACTION_MOVE) {
5128 if(mFatTouch) {
5129 //two cases here
5130 //an invalid down followed by 0 or moves(valid or invalid)
Romain Guy06882f82009-06-10 13:36:04 -07005131 //a valid down, invalid move, more moves. want to ignore till up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005132 returnFlag = true;
5133 } else if(cheekPress) {
5134 //valid down followed by invalid moves
5135 //an invalid move have to cancel earlier action
5136 ev.setAction(MotionEvent.ACTION_CANCEL);
5137 action = MotionEvent.ACTION_CANCEL;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005138 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139 //note that the subsequent invalid moves will not get here
5140 mFatTouch = true;
5141 }
5142 }
5143 } //else if action
5144 if(returnFlag) {
5145 //recycle que, ev
5146 if (qev != null) {
5147 mQueue.recycleEvent(qev);
5148 }
5149 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005150 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 }
5152 } //end if target
Michael Chane96440f2009-05-06 10:27:36 -07005153
Michael Chan9f028e62009-08-04 17:37:46 -07005154 // Enable this for testing the "right" value
5155 if (false && action == MotionEvent.ACTION_DOWN) {
Michael Chane96440f2009-05-06 10:27:36 -07005156 int max_events_per_sec = 35;
5157 try {
5158 max_events_per_sec = Integer.parseInt(SystemProperties
5159 .get("windowsmgr.max_events_per_sec"));
5160 if (max_events_per_sec < 1) {
5161 max_events_per_sec = 35;
5162 }
5163 } catch (NumberFormatException e) {
5164 }
5165 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
5166 }
5167
5168 /*
5169 * Throttle events to minimize CPU usage when there's a flood of events
5170 * e.g. constant contact with the screen
5171 */
5172 if (action == MotionEvent.ACTION_MOVE) {
5173 long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
5174 long now = SystemClock.uptimeMillis();
5175 if (now < nextEventTime) {
5176 try {
5177 Thread.sleep(nextEventTime - now);
5178 } catch (InterruptedException e) {
5179 }
5180 mLastTouchEventTime = nextEventTime;
5181 } else {
5182 mLastTouchEventTime = now;
5183 }
5184 }
5185
Michael Chan53071d62009-05-13 17:29:48 -07005186 if (MEASURE_LATENCY) {
5187 lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5188 }
5189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005190 synchronized(mWindowMap) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005191 if (!target.isVisibleLw()) {
5192 // During this motion dispatch, the target window has become
5193 // invisible.
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005194 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005195 if (qev != null) {
5196 mQueue.recycleEvent(qev);
5197 }
5198 ev.recycle();
5199 return INJECT_SUCCEEDED;
5200 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005202 if (qev != null && action == MotionEvent.ACTION_MOVE) {
5203 mKeyWaiter.bindTargetWindowLocked(target,
5204 KeyWaiter.RETURN_PENDING_POINTER, qev);
5205 ev = null;
5206 } else {
5207 if (action == MotionEvent.ACTION_DOWN) {
5208 WindowState out = mKeyWaiter.mOutsideTouchTargets;
5209 if (out != null) {
5210 MotionEvent oev = MotionEvent.obtain(ev);
5211 oev.setAction(MotionEvent.ACTION_OUTSIDE);
5212 do {
5213 final Rect frame = out.mFrame;
5214 oev.offsetLocation(-(float)frame.left, -(float)frame.top);
5215 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005216 out.mClient.dispatchPointer(oev, eventTime, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005217 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005218 Slog.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 }
5220 oev.offsetLocation((float)frame.left, (float)frame.top);
5221 out = out.mNextOutsideTouch;
5222 } while (out != null);
5223 mKeyWaiter.mOutsideTouchTargets = null;
5224 }
5225 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005226
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005227 dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005228
Dianne Hackborn6adba242009-11-10 11:10:09 -08005229 final Rect frame = target.mFrame;
5230 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
5231 mKeyWaiter.bindTargetWindowLocked(target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 }
5233 }
Romain Guy06882f82009-06-10 13:36:04 -07005234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005235 // finally offset the event to the target's coordinate system and
5236 // dispatch the event.
5237 try {
5238 if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005239 Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005240 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005241
Michael Chan53071d62009-05-13 17:29:48 -07005242 if (MEASURE_LATENCY) {
5243 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
5244 }
5245
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005246 target.mClient.dispatchPointer(ev, eventTime, true);
Michael Chan53071d62009-05-13 17:29:48 -07005247
5248 if (MEASURE_LATENCY) {
5249 lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
5250 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005251 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005252 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005253 Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 mKeyWaiter.mMotionTarget = null;
5255 try {
5256 removeWindow(target.mSession, target.mClient);
5257 } catch (java.util.NoSuchElementException ex) {
5258 // This will happen if the window has already been
5259 // removed.
5260 }
5261 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005262 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 }
Romain Guy06882f82009-06-10 13:36:04 -07005264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005265 /**
5266 * @return Returns true if event was dispatched, false if it was dropped for any reason
5267 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005268 private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005269 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
Romain Guy06882f82009-06-10 13:36:04 -07005271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005273 ev, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005275 Slog.w(TAG, "No focus window, dropping trackball: " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 if (qev != null) {
5277 mQueue.recycleEvent(qev);
5278 }
5279 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005280 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281 }
5282 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
5283 if (qev != null) {
5284 mQueue.recycleEvent(qev);
5285 }
5286 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005287 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 }
Romain Guy06882f82009-06-10 13:36:04 -07005289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005292 if (uid != 0 && uid != focus.mSession.mUid) {
5293 if (mContext.checkPermission(
5294 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5295 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005296 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 + pid + " uid " + uid + " to window " + focus
5298 + " owned by uid " + focus.mSession.mUid);
5299 if (qev != null) {
5300 mQueue.recycleEvent(qev);
5301 }
5302 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005303 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 }
5305 }
Romain Guy06882f82009-06-10 13:36:04 -07005306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 final long eventTime = ev.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 synchronized(mWindowMap) {
5310 if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
5311 mKeyWaiter.bindTargetWindowLocked(focus,
5312 KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
5313 // We don't deliver movement events to the client, we hold
5314 // them and wait for them to call back.
5315 ev = null;
5316 } else {
5317 mKeyWaiter.bindTargetWindowLocked(focus);
5318 }
5319 }
Romain Guy06882f82009-06-10 13:36:04 -07005320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005322 focus.mClient.dispatchTrackball(ev, eventTime, true);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005323 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005325 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005326 try {
5327 removeWindow(focus.mSession, focus.mClient);
5328 } catch (java.util.NoSuchElementException ex) {
5329 // This will happen if the window has already been
5330 // removed.
5331 }
5332 }
Romain Guy06882f82009-06-10 13:36:04 -07005333
Dianne Hackborncfaef692009-06-15 14:24:44 -07005334 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 }
Romain Guy06882f82009-06-10 13:36:04 -07005336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 /**
5338 * @return Returns true if event was dispatched, false if it was dropped for any reason
5339 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005340 private int dispatchKey(KeyEvent event, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005341 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342
5343 Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005344 null, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005346 Slog.w(TAG, "No focus window, dropping: " + event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005347 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 }
5349 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005350 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 }
Romain Guy06882f82009-06-10 13:36:04 -07005352
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07005353 // Okay we have finished waiting for the last event to be processed.
5354 // First off, if this is a repeat event, check to see if there is
5355 // a corresponding up event in the queue. If there is, we will
5356 // just drop the repeat, because it makes no sense to repeat after
5357 // the user has released a key. (This is especially important for
5358 // long presses.)
5359 if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
5360 return INJECT_SUCCEEDED;
5361 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005363 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005364
Joe Onorato8a9b2202010-02-26 18:56:32 -08005365 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 TAG, "Dispatching to " + focus + ": " + event);
5367
5368 if (uid != 0 && uid != focus.mSession.mUid) {
5369 if (mContext.checkPermission(
5370 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5371 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005372 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 + pid + " uid " + uid + " to window " + focus
5374 + " owned by uid " + focus.mSession.mUid);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005375 return INJECT_NO_PERMISSION;
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 synchronized(mWindowMap) {
5380 mKeyWaiter.bindTargetWindowLocked(focus);
5381 }
5382
5383 // NOSHIP extra state logging
5384 mKeyWaiter.recordDispatchState(event, focus);
5385 // END NOSHIP
Romain Guy06882f82009-06-10 13:36:04 -07005386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 try {
5388 if (DEBUG_INPUT || DEBUG_FOCUS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005389 Slog.v(TAG, "Delivering key " + event.getKeyCode()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 + " to " + focus);
5391 }
5392 focus.mClient.dispatchKey(event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005393 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005394 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005395 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 try {
5397 removeWindow(focus.mSession, focus.mClient);
5398 } catch (java.util.NoSuchElementException ex) {
5399 // This will happen if the window has already been
5400 // removed.
5401 }
5402 }
Romain Guy06882f82009-06-10 13:36:04 -07005403
Dianne Hackborncfaef692009-06-15 14:24:44 -07005404 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 }
Romain Guy06882f82009-06-10 13:36:04 -07005406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 public void pauseKeyDispatching(IBinder _token) {
5408 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5409 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005410 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005411 }
5412
5413 synchronized (mWindowMap) {
5414 WindowToken token = mTokenMap.get(_token);
5415 if (token != null) {
5416 mKeyWaiter.pauseDispatchingLocked(token);
5417 }
5418 }
5419 }
5420
5421 public void resumeKeyDispatching(IBinder _token) {
5422 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5423 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005424 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 }
5426
5427 synchronized (mWindowMap) {
5428 WindowToken token = mTokenMap.get(_token);
5429 if (token != null) {
5430 mKeyWaiter.resumeDispatchingLocked(token);
5431 }
5432 }
5433 }
5434
5435 public void setEventDispatching(boolean enabled) {
5436 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5437 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005438 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 }
5440
5441 synchronized (mWindowMap) {
5442 mKeyWaiter.setEventDispatchingLocked(enabled);
5443 }
5444 }
Romain Guy06882f82009-06-10 13:36:04 -07005445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 /**
5447 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005448 *
5449 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 * {@link SystemClock#uptimeMillis()} as the timebase.)
5451 * @param sync If true, wait for the event to be completed before returning to the caller.
5452 * @return Returns true if event was dispatched, false if it was dropped for any reason
5453 */
5454 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5455 long downTime = ev.getDownTime();
5456 long eventTime = ev.getEventTime();
5457
5458 int action = ev.getAction();
5459 int code = ev.getKeyCode();
5460 int repeatCount = ev.getRepeatCount();
5461 int metaState = ev.getMetaState();
5462 int deviceId = ev.getDeviceId();
5463 int scancode = ev.getScanCode();
5464
5465 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5466 if (downTime == 0) downTime = eventTime;
5467
5468 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07005469 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005471 final int pid = Binder.getCallingPid();
5472 final int uid = Binder.getCallingUid();
5473 final long ident = Binder.clearCallingIdentity();
5474 final int result = dispatchKey(newEvent, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 if (sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005476 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 }
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005478 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005479 switch (result) {
5480 case INJECT_NO_PERMISSION:
5481 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305482 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005483 case INJECT_SUCCEEDED:
5484 return true;
5485 }
5486 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 }
5488
5489 /**
5490 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005491 *
5492 * @param ev A motion event describing the pointer (touch) action. (As noted in
5493 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 * {@link SystemClock#uptimeMillis()} as the timebase.)
5495 * @param sync If true, wait for the event to be completed before returning to the caller.
5496 * @return Returns true if event was dispatched, false if it was dropped for any reason
5497 */
5498 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005499 final int pid = Binder.getCallingPid();
5500 final int uid = Binder.getCallingUid();
5501 final long ident = Binder.clearCallingIdentity();
5502 final int result = dispatchPointer(null, ev, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 if (sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005504 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 }
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005506 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005507 switch (result) {
5508 case INJECT_NO_PERMISSION:
5509 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305510 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005511 case INJECT_SUCCEEDED:
5512 return true;
5513 }
5514 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 }
Romain Guy06882f82009-06-10 13:36:04 -07005516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005517 /**
5518 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005519 *
5520 * @param ev A motion event describing the trackball action. (As noted in
5521 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 * {@link SystemClock#uptimeMillis()} as the timebase.)
5523 * @param sync If true, wait for the event to be completed before returning to the caller.
5524 * @return Returns true if event was dispatched, false if it was dropped for any reason
5525 */
5526 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005527 final int pid = Binder.getCallingPid();
5528 final int uid = Binder.getCallingUid();
5529 final long ident = Binder.clearCallingIdentity();
5530 final int result = dispatchTrackball(null, ev, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 if (sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005532 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 }
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005534 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005535 switch (result) {
5536 case INJECT_NO_PERMISSION:
5537 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305538 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005539 case INJECT_SUCCEEDED:
5540 return true;
5541 }
5542 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 }
Romain Guy06882f82009-06-10 13:36:04 -07005544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 private WindowState getFocusedWindow() {
5546 synchronized (mWindowMap) {
5547 return getFocusedWindowLocked();
5548 }
5549 }
5550
5551 private WindowState getFocusedWindowLocked() {
5552 return mCurrentFocus;
5553 }
Romain Guy06882f82009-06-10 13:36:04 -07005554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 /**
5556 * This class holds the state for dispatching key events. This state
5557 * is protected by the KeyWaiter instance, NOT by the window lock. You
5558 * can be holding the main window lock while acquire the KeyWaiter lock,
5559 * but not the other way around.
5560 */
5561 final class KeyWaiter {
5562 // NOSHIP debugging
5563 public class DispatchState {
5564 private KeyEvent event;
5565 private WindowState focus;
5566 private long time;
5567 private WindowState lastWin;
5568 private IBinder lastBinder;
5569 private boolean finished;
5570 private boolean gotFirstWindow;
5571 private boolean eventDispatching;
5572 private long timeToSwitch;
5573 private boolean wasFrozen;
5574 private boolean focusPaused;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005575 private WindowState curFocus;
Romain Guy06882f82009-06-10 13:36:04 -07005576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 DispatchState(KeyEvent theEvent, WindowState theFocus) {
5578 focus = theFocus;
5579 event = theEvent;
5580 time = System.currentTimeMillis();
5581 // snapshot KeyWaiter state
5582 lastWin = mLastWin;
5583 lastBinder = mLastBinder;
5584 finished = mFinished;
5585 gotFirstWindow = mGotFirstWindow;
5586 eventDispatching = mEventDispatching;
5587 timeToSwitch = mTimeToSwitch;
5588 wasFrozen = mWasFrozen;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005589 curFocus = mCurrentFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 // cache the paused state at ctor time as well
5591 if (theFocus == null || theFocus.mToken == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 focusPaused = false;
5593 } else {
5594 focusPaused = theFocus.mToken.paused;
5595 }
5596 }
Romain Guy06882f82009-06-10 13:36:04 -07005597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 public String toString() {
5599 return "{{" + event + " to " + focus + " @ " + time
5600 + " lw=" + lastWin + " lb=" + lastBinder
5601 + " fin=" + finished + " gfw=" + gotFirstWindow
5602 + " ed=" + eventDispatching + " tts=" + timeToSwitch
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005603 + " wf=" + wasFrozen + " fp=" + focusPaused
Christopher Tate46d45252010-02-09 15:48:57 -08005604 + " mcf=" + curFocus + "}}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 }
5606 };
5607 private DispatchState mDispatchState = null;
5608 public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
5609 mDispatchState = new DispatchState(theEvent, theFocus);
5610 }
5611 // END NOSHIP
5612
5613 public static final int RETURN_NOTHING = 0;
5614 public static final int RETURN_PENDING_POINTER = 1;
5615 public static final int RETURN_PENDING_TRACKBALL = 2;
Romain Guy06882f82009-06-10 13:36:04 -07005616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 final Object SKIP_TARGET_TOKEN = new Object();
5618 final Object CONSUMED_EVENT_TOKEN = new Object();
Romain Guy06882f82009-06-10 13:36:04 -07005619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005620 private WindowState mLastWin = null;
5621 private IBinder mLastBinder = null;
5622 private boolean mFinished = true;
5623 private boolean mGotFirstWindow = false;
5624 private boolean mEventDispatching = true;
5625 private long mTimeToSwitch = 0;
5626 /* package */ boolean mWasFrozen = false;
Romain Guy06882f82009-06-10 13:36:04 -07005627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 // Target of Motion events
5629 WindowState mMotionTarget;
Romain Guy06882f82009-06-10 13:36:04 -07005630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 // Windows above the target who would like to receive an "outside"
5632 // touch event for any down events outside of them.
5633 WindowState mOutsideTouchTargets;
5634
5635 /**
5636 * Wait for the last event dispatch to complete, then find the next
5637 * target that should receive the given event and wait for that one
5638 * to be ready to receive it.
5639 */
5640 Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
5641 MotionEvent nextMotion, boolean isPointerEvent,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005642 boolean failIfTimeout, int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 long startTime = SystemClock.uptimeMillis();
5644 long keyDispatchingTimeout = 5 * 1000;
5645 long waitedFor = 0;
5646
5647 while (true) {
5648 // Figure out which window we care about. It is either the
5649 // last window we are waiting to have process the event or,
5650 // if none, then the next window we think the event should go
5651 // to. Note: we retrieve mLastWin outside of the lock, so
5652 // it may change before we lock. Thus we must check it again.
5653 WindowState targetWin = mLastWin;
5654 boolean targetIsNew = targetWin == null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005655 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005656 TAG, "waitForLastKey: mFinished=" + mFinished +
5657 ", mLastWin=" + mLastWin);
5658 if (targetIsNew) {
5659 Object target = findTargetWindow(nextKey, qev, nextMotion,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005660 isPointerEvent, callingPid, callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005661 if (target == SKIP_TARGET_TOKEN) {
5662 // The user has pressed a special key, and we are
5663 // dropping all pending events before it.
Joe Onorato8a9b2202010-02-26 18:56:32 -08005664 if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 + " " + nextMotion);
5666 return null;
5667 }
5668 if (target == CONSUMED_EVENT_TOKEN) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005669 if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 + " " + nextMotion);
5671 return target;
5672 }
5673 targetWin = (WindowState)target;
5674 }
Romain Guy06882f82009-06-10 13:36:04 -07005675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 AppWindowToken targetApp = null;
Romain Guy06882f82009-06-10 13:36:04 -07005677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005678 // Now: is it okay to send the next event to this window?
5679 synchronized (this) {
5680 // First: did we come here based on the last window not
5681 // being null, but it changed by the time we got here?
5682 // If so, try again.
5683 if (!targetIsNew && mLastWin == null) {
5684 continue;
5685 }
Romain Guy06882f82009-06-10 13:36:04 -07005686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005687 // We never dispatch events if not finished with the
5688 // last one, or the display is frozen.
5689 if (mFinished && !mDisplayFrozen) {
5690 // If event dispatching is disabled, then we
5691 // just consume the events.
5692 if (!mEventDispatching) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005693 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005694 "Skipping event; dispatching disabled: "
5695 + nextKey + " " + nextMotion);
5696 return null;
5697 }
5698 if (targetWin != null) {
5699 // If this is a new target, and that target is not
5700 // paused or unresponsive, then all looks good to
5701 // handle the event.
5702 if (targetIsNew && !targetWin.mToken.paused) {
5703 return targetWin;
5704 }
Romain Guy06882f82009-06-10 13:36:04 -07005705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 // If we didn't find a target window, and there is no
5707 // focused app window, then just eat the events.
5708 } else if (mFocusedApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005709 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 "Skipping event; no focused app: "
5711 + nextKey + " " + nextMotion);
5712 return null;
5713 }
5714 }
Romain Guy06882f82009-06-10 13:36:04 -07005715
Joe Onorato8a9b2202010-02-26 18:56:32 -08005716 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005717 TAG, "Waiting for last key in " + mLastBinder
5718 + " target=" + targetWin
5719 + " mFinished=" + mFinished
5720 + " mDisplayFrozen=" + mDisplayFrozen
5721 + " targetIsNew=" + targetIsNew
5722 + " paused="
5723 + (targetWin != null ? targetWin.mToken.paused : false)
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005724 + " mFocusedApp=" + mFocusedApp
5725 + " mCurrentFocus=" + mCurrentFocus);
Romain Guy06882f82009-06-10 13:36:04 -07005726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005727 targetApp = targetWin != null
5728 ? targetWin.mAppToken : mFocusedApp;
Romain Guy06882f82009-06-10 13:36:04 -07005729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005730 long curTimeout = keyDispatchingTimeout;
5731 if (mTimeToSwitch != 0) {
5732 long now = SystemClock.uptimeMillis();
5733 if (mTimeToSwitch <= now) {
5734 // If an app switch key has been pressed, and we have
5735 // waited too long for the current app to finish
5736 // processing keys, then wait no more!
Christopher Tate136b1f92010-02-11 17:51:24 -08005737 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005738 continue;
5739 }
5740 long switchTimeout = mTimeToSwitch - now;
5741 if (curTimeout > switchTimeout) {
5742 curTimeout = switchTimeout;
5743 }
5744 }
Romain Guy06882f82009-06-10 13:36:04 -07005745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746 try {
5747 // after that continue
5748 // processing keys, so we don't get stuck.
Joe Onorato8a9b2202010-02-26 18:56:32 -08005749 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 TAG, "Waiting for key dispatch: " + curTimeout);
5751 wait(curTimeout);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005752 if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 + SystemClock.uptimeMillis() + " startTime="
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005754 + startTime + " switchTime=" + mTimeToSwitch
5755 + " target=" + targetWin + " mLW=" + mLastWin
5756 + " mLB=" + mLastBinder + " fin=" + mFinished
5757 + " mCurrentFocus=" + mCurrentFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 } catch (InterruptedException e) {
5759 }
5760 }
5761
5762 // If we were frozen during configuration change, restart the
5763 // timeout checks from now; otherwise look at whether we timed
5764 // out before awakening.
5765 if (mWasFrozen) {
5766 waitedFor = 0;
5767 mWasFrozen = false;
5768 } else {
5769 waitedFor = SystemClock.uptimeMillis() - startTime;
5770 }
5771
5772 if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
5773 IApplicationToken at = null;
5774 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005775 Slog.w(TAG, "Key dispatching timed out sending to " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 (targetWin != null ? targetWin.mAttrs.getTitle()
Ken Shirriff8200b202010-02-04 13:34:37 -08005777 : "<null>: no window ready for key dispatch"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 // NOSHIP debugging
Joe Onorato8a9b2202010-02-26 18:56:32 -08005779 Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
5780 Slog.w(TAG, "Current dispatch state: " +
Ken Shirriff8200b202010-02-04 13:34:37 -08005781 new DispatchState(nextKey, targetWin));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 // END NOSHIP
5783 //dump();
5784 if (targetWin != null) {
5785 at = targetWin.getAppToken();
5786 } else if (targetApp != null) {
5787 at = targetApp.appToken;
5788 }
5789 }
5790
5791 boolean abort = true;
5792 if (at != null) {
5793 try {
5794 long timeout = at.getKeyDispatchingTimeout();
5795 if (timeout > waitedFor) {
5796 // we did not wait the proper amount of time for this application.
5797 // set the timeout to be the real timeout and wait again.
5798 keyDispatchingTimeout = timeout - waitedFor;
5799 continue;
5800 } else {
5801 abort = at.keyDispatchingTimedOut();
5802 }
5803 } catch (RemoteException ex) {
5804 }
5805 }
5806
5807 synchronized (this) {
5808 if (abort && (mLastWin == targetWin || targetWin == null)) {
5809 mFinished = true;
Romain Guy06882f82009-06-10 13:36:04 -07005810 if (mLastWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005811 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 "Window " + mLastWin +
5813 " timed out on key input");
5814 if (mLastWin.mToken.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005815 Slog.w(TAG, "Un-pausing dispatching to this window");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 mLastWin.mToken.paused = false;
5817 }
5818 }
5819 if (mMotionTarget == targetWin) {
5820 mMotionTarget = null;
5821 }
5822 mLastWin = null;
5823 mLastBinder = null;
5824 if (failIfTimeout || targetWin == null) {
5825 return null;
5826 }
5827 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005828 Slog.w(TAG, "Continuing to wait for key to be dispatched");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 startTime = SystemClock.uptimeMillis();
5830 }
5831 }
5832 }
5833 }
5834 }
Romain Guy06882f82009-06-10 13:36:04 -07005835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005836 Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005837 MotionEvent nextMotion, boolean isPointerEvent,
5838 int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 mOutsideTouchTargets = null;
Romain Guy06882f82009-06-10 13:36:04 -07005840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 if (nextKey != null) {
5842 // Find the target window for a normal key event.
5843 final int keycode = nextKey.getKeyCode();
5844 final int repeatCount = nextKey.getRepeatCount();
5845 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
5846 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 if (!dispatch) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005849 if (callingUid == 0 ||
5850 mContext.checkPermission(
5851 android.Manifest.permission.INJECT_EVENTS,
5852 callingPid, callingUid)
5853 == PackageManager.PERMISSION_GRANTED) {
5854 mPolicy.interceptKeyTi(null, keycode,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07005855 nextKey.getMetaState(), down, repeatCount,
5856 nextKey.getFlags());
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005857 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005858 Slog.w(TAG, "Event timeout during app switch: dropping "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005859 + nextKey);
5860 return SKIP_TARGET_TOKEN;
5861 }
Romain Guy06882f82009-06-10 13:36:04 -07005862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 WindowState focus = null;
5866 synchronized(mWindowMap) {
5867 focus = getFocusedWindowLocked();
5868 }
Romain Guy06882f82009-06-10 13:36:04 -07005869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005870 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
Romain Guy06882f82009-06-10 13:36:04 -07005871
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005872 if (callingUid == 0 ||
5873 (focus != null && callingUid == focus.mSession.mUid) ||
5874 mContext.checkPermission(
5875 android.Manifest.permission.INJECT_EVENTS,
5876 callingPid, callingUid)
5877 == PackageManager.PERMISSION_GRANTED) {
5878 if (mPolicy.interceptKeyTi(focus,
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005879 keycode, nextKey.getMetaState(), down, repeatCount,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07005880 nextKey.getFlags())) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005881 return CONSUMED_EVENT_TOKEN;
5882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005883 }
Romain Guy06882f82009-06-10 13:36:04 -07005884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 return focus;
Romain Guy06882f82009-06-10 13:36:04 -07005886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887 } else if (!isPointerEvent) {
5888 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
5889 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005890 Slog.w(TAG, "Event timeout during app switch: dropping trackball "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 + nextMotion);
5892 return SKIP_TARGET_TOKEN;
5893 }
Romain Guy06882f82009-06-10 13:36:04 -07005894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005895 WindowState focus = null;
5896 synchronized(mWindowMap) {
5897 focus = getFocusedWindowLocked();
5898 }
Romain Guy06882f82009-06-10 13:36:04 -07005899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
5901 return focus;
5902 }
Romain Guy06882f82009-06-10 13:36:04 -07005903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005904 if (nextMotion == null) {
5905 return SKIP_TARGET_TOKEN;
5906 }
Romain Guy06882f82009-06-10 13:36:04 -07005907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
5909 KeyEvent.KEYCODE_UNKNOWN);
5910 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005911 Slog.w(TAG, "Event timeout during app switch: dropping pointer "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 + nextMotion);
5913 return SKIP_TARGET_TOKEN;
5914 }
Romain Guy06882f82009-06-10 13:36:04 -07005915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 // Find the target window for a pointer event.
5917 int action = nextMotion.getAction();
5918 final float xf = nextMotion.getX();
5919 final float yf = nextMotion.getY();
5920 final long eventTime = nextMotion.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005922 final boolean screenWasOff = qev != null
5923 && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07005924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005925 WindowState target = null;
Romain Guy06882f82009-06-10 13:36:04 -07005926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005927 synchronized(mWindowMap) {
5928 synchronized (this) {
5929 if (action == MotionEvent.ACTION_DOWN) {
5930 if (mMotionTarget != null) {
5931 // this is weird, we got a pen down, but we thought it was
5932 // already down!
5933 // XXX: We should probably send an ACTION_UP to the current
5934 // target.
Joe Onorato8a9b2202010-02-26 18:56:32 -08005935 Slog.w(TAG, "Pointer down received while already down in: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 + mMotionTarget);
5937 mMotionTarget = null;
5938 }
Romain Guy06882f82009-06-10 13:36:04 -07005939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 // ACTION_DOWN is special, because we need to lock next events to
5941 // the window we'll land onto.
5942 final int x = (int)xf;
5943 final int y = (int)yf;
Romain Guy06882f82009-06-10 13:36:04 -07005944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 final ArrayList windows = mWindows;
5946 final int N = windows.size();
5947 WindowState topErrWindow = null;
5948 final Rect tmpRect = mTempRect;
5949 for (int i=N-1; i>=0; i--) {
5950 WindowState child = (WindowState)windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005951 //Slog.i(TAG, "Checking dispatch to: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 final int flags = child.mAttrs.flags;
5953 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
5954 if (topErrWindow == null) {
5955 topErrWindow = child;
5956 }
5957 }
5958 if (!child.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005959 //Slog.i(TAG, "Not visible!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 continue;
5961 }
5962 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005963 //Slog.i(TAG, "Not touchable!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 if ((flags & WindowManager.LayoutParams
5965 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
5966 child.mNextOutsideTouch = mOutsideTouchTargets;
5967 mOutsideTouchTargets = child;
5968 }
5969 continue;
5970 }
5971 tmpRect.set(child.mFrame);
5972 if (child.mTouchableInsets == ViewTreeObserver
5973 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
5974 // The touch is inside of the window if it is
5975 // inside the frame, AND the content part of that
5976 // frame that was given by the application.
5977 tmpRect.left += child.mGivenContentInsets.left;
5978 tmpRect.top += child.mGivenContentInsets.top;
5979 tmpRect.right -= child.mGivenContentInsets.right;
5980 tmpRect.bottom -= child.mGivenContentInsets.bottom;
5981 } else if (child.mTouchableInsets == ViewTreeObserver
5982 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
5983 // The touch is inside of the window if it is
5984 // inside the frame, AND the visible part of that
5985 // frame that was given by the application.
5986 tmpRect.left += child.mGivenVisibleInsets.left;
5987 tmpRect.top += child.mGivenVisibleInsets.top;
5988 tmpRect.right -= child.mGivenVisibleInsets.right;
5989 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
5990 }
5991 final int touchFlags = flags &
5992 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5993 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
5994 if (tmpRect.contains(x, y) || touchFlags == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005995 //Slog.i(TAG, "Using this target!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 if (!screenWasOff || (flags &
5997 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
5998 mMotionTarget = child;
5999 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006000 //Slog.i(TAG, "Waking, skip!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006001 mMotionTarget = null;
6002 }
6003 break;
6004 }
Romain Guy06882f82009-06-10 13:36:04 -07006005
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006006 if ((flags & WindowManager.LayoutParams
6007 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6008 child.mNextOutsideTouch = mOutsideTouchTargets;
6009 mOutsideTouchTargets = child;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006010 //Slog.i(TAG, "Adding to outside target list: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011 }
6012 }
6013
6014 // if there's an error window but it's not accepting
6015 // focus (typically because it is not yet visible) just
6016 // wait for it -- any other focused window may in fact
6017 // be in ANR state.
6018 if (topErrWindow != null && mMotionTarget != topErrWindow) {
6019 mMotionTarget = null;
6020 }
6021 }
Romain Guy06882f82009-06-10 13:36:04 -07006022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006023 target = mMotionTarget;
6024 }
6025 }
Romain Guy06882f82009-06-10 13:36:04 -07006026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 wakeupIfNeeded(target, eventType(nextMotion));
Romain Guy06882f82009-06-10 13:36:04 -07006028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006029 // Pointer events are a little different -- if there isn't a
6030 // target found for any event, then just drop it.
6031 return target != null ? target : SKIP_TARGET_TOKEN;
6032 }
Romain Guy06882f82009-06-10 13:36:04 -07006033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006034 boolean checkShouldDispatchKey(int keycode) {
6035 synchronized (this) {
6036 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
6037 mTimeToSwitch = 0;
6038 return true;
6039 }
6040 if (mTimeToSwitch != 0
6041 && mTimeToSwitch < SystemClock.uptimeMillis()) {
6042 return false;
6043 }
6044 return true;
6045 }
6046 }
Romain Guy06882f82009-06-10 13:36:04 -07006047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 void bindTargetWindowLocked(WindowState win,
6049 int pendingWhat, QueuedEvent pendingMotion) {
6050 synchronized (this) {
6051 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
6052 }
6053 }
Romain Guy06882f82009-06-10 13:36:04 -07006054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 void bindTargetWindowLocked(WindowState win) {
6056 synchronized (this) {
6057 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
6058 }
6059 }
6060
6061 void bindTargetWindowLockedLocked(WindowState win,
6062 int pendingWhat, QueuedEvent pendingMotion) {
6063 mLastWin = win;
6064 mLastBinder = win.mClient.asBinder();
6065 mFinished = false;
6066 if (pendingMotion != null) {
6067 final Session s = win.mSession;
6068 if (pendingWhat == RETURN_PENDING_POINTER) {
6069 releasePendingPointerLocked(s);
6070 s.mPendingPointerMove = pendingMotion;
6071 s.mPendingPointerWindow = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006072 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006073 "bindTargetToWindow " + s.mPendingPointerMove);
6074 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
6075 releasePendingTrackballLocked(s);
6076 s.mPendingTrackballMove = pendingMotion;
6077 s.mPendingTrackballWindow = win;
6078 }
6079 }
6080 }
Romain Guy06882f82009-06-10 13:36:04 -07006081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 void releasePendingPointerLocked(Session s) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006083 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006084 "releasePendingPointer " + s.mPendingPointerMove);
6085 if (s.mPendingPointerMove != null) {
6086 mQueue.recycleEvent(s.mPendingPointerMove);
6087 s.mPendingPointerMove = null;
6088 }
6089 }
Romain Guy06882f82009-06-10 13:36:04 -07006090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 void releasePendingTrackballLocked(Session s) {
6092 if (s.mPendingTrackballMove != null) {
6093 mQueue.recycleEvent(s.mPendingTrackballMove);
6094 s.mPendingTrackballMove = null;
6095 }
6096 }
Romain Guy06882f82009-06-10 13:36:04 -07006097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 MotionEvent finishedKey(Session session, IWindow client, boolean force,
6099 int returnWhat) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006100 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 TAG, "finishedKey: client=" + client + ", force=" + force);
6102
6103 if (client == null) {
6104 return null;
6105 }
6106
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006107 MotionEvent res = null;
6108 QueuedEvent qev = null;
6109 WindowState win = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006112 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 TAG, "finishedKey: client=" + client.asBinder()
6114 + ", force=" + force + ", last=" + mLastBinder
6115 + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
6116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 if (returnWhat == RETURN_PENDING_POINTER) {
6118 qev = session.mPendingPointerMove;
6119 win = session.mPendingPointerWindow;
6120 session.mPendingPointerMove = null;
6121 session.mPendingPointerWindow = null;
6122 } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
6123 qev = session.mPendingTrackballMove;
6124 win = session.mPendingTrackballWindow;
6125 session.mPendingTrackballMove = null;
6126 session.mPendingTrackballWindow = null;
6127 }
Romain Guy06882f82009-06-10 13:36:04 -07006128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 if (mLastBinder == client.asBinder()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006130 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006131 TAG, "finishedKey: last paused="
6132 + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
6133 if (mLastWin != null && (!mLastWin.mToken.paused || force
6134 || !mEventDispatching)) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006135 doFinishedKeyLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006136 } else {
6137 // Make sure to wake up anyone currently waiting to
6138 // dispatch a key, so they can re-evaluate their
6139 // current situation.
6140 mFinished = true;
6141 notifyAll();
6142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006143 }
Romain Guy06882f82009-06-10 13:36:04 -07006144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 if (qev != null) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006146 res = (MotionEvent)qev.event;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006147 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006148 "Returning pending motion: " + res);
6149 mQueue.recycleEvent(qev);
6150 if (win != null && returnWhat == RETURN_PENDING_POINTER) {
6151 res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
6152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 }
Christopher Tate2624fbc2009-12-11 12:11:31 -08006154 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006155
Christopher Tate2624fbc2009-12-11 12:11:31 -08006156 if (res != null && returnWhat == RETURN_PENDING_POINTER) {
6157 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08006158 dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006159 }
6160 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006161
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006162 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006163 }
6164
6165 void tickle() {
6166 synchronized (this) {
6167 notifyAll();
6168 }
6169 }
Romain Guy06882f82009-06-10 13:36:04 -07006170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 void handleNewWindowLocked(WindowState newWindow) {
6172 if (!newWindow.canReceiveKeys()) {
6173 return;
6174 }
6175 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006176 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 TAG, "New key dispatch window: win="
6178 + newWindow.mClient.asBinder()
6179 + ", last=" + mLastBinder
6180 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6181 + "), finished=" + mFinished + ", paused="
6182 + newWindow.mToken.paused);
6183
6184 // Displaying a window implicitly causes dispatching to
6185 // be unpaused. (This is to protect against bugs if someone
6186 // pauses dispatching but forgets to resume.)
6187 newWindow.mToken.paused = false;
6188
6189 mGotFirstWindow = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190
6191 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006192 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006193 "New SYSTEM_ERROR window; resetting state");
6194 mLastWin = null;
6195 mLastBinder = null;
6196 mMotionTarget = null;
6197 mFinished = true;
6198 } else if (mLastWin != null) {
6199 // If the new window is above the window we are
6200 // waiting on, then stop waiting and let key dispatching
6201 // start on the new guy.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006202 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 TAG, "Last win layer=" + mLastWin.mLayer
6204 + ", new win layer=" + newWindow.mLayer);
6205 if (newWindow.mLayer >= mLastWin.mLayer) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006206 // The new window is above the old; finish pending input to the last
6207 // window and start directing it to the new one.
6208 mLastWin.mToken.paused = false;
Christopher Tate136b1f92010-02-11 17:51:24 -08006209 doFinishedKeyLocked(false); // does a notifyAll()
6210 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211 }
6212 }
6213
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006214 // Now that we've put a new window state in place, make the event waiter
6215 // take notice and retarget its attentions.
6216 notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006217 }
6218 }
6219
6220 void pauseDispatchingLocked(WindowToken token) {
6221 synchronized (this)
6222 {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006223 if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006224 token.paused = true;
6225
6226 /*
6227 if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
6228 mPaused = true;
6229 } else {
6230 if (mLastWin == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006231 Slog.i(TAG, "Key dispatching not paused: no last window.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 } else if (mFinished) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006233 Slog.i(TAG, "Key dispatching not paused: finished last key.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006235 Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 }
6237 }
6238 */
6239 }
6240 }
6241
6242 void resumeDispatchingLocked(WindowToken token) {
6243 synchronized (this) {
6244 if (token.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006245 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006246 TAG, "Resuming WindowToken " + token
6247 + ", last=" + mLastBinder
6248 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6249 + "), finished=" + mFinished + ", paused="
6250 + token.paused);
6251 token.paused = false;
6252 if (mLastWin != null && mLastWin.mToken == token && mFinished) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006253 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006254 } else {
6255 notifyAll();
6256 }
6257 }
6258 }
6259 }
6260
6261 void setEventDispatchingLocked(boolean enabled) {
6262 synchronized (this) {
6263 mEventDispatching = enabled;
6264 notifyAll();
6265 }
6266 }
Romain Guy06882f82009-06-10 13:36:04 -07006267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006268 void appSwitchComing() {
6269 synchronized (this) {
6270 // Don't wait for more than .5 seconds for app to finish
6271 // processing the pending events.
6272 long now = SystemClock.uptimeMillis() + 500;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006273 if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006274 if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
6275 mTimeToSwitch = now;
6276 }
6277 notifyAll();
6278 }
6279 }
Romain Guy06882f82009-06-10 13:36:04 -07006280
Christopher Tate136b1f92010-02-11 17:51:24 -08006281 private final void doFinishedKeyLocked(boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006282 if (mLastWin != null) {
6283 releasePendingPointerLocked(mLastWin.mSession);
6284 releasePendingTrackballLocked(mLastWin.mSession);
6285 }
Romain Guy06882f82009-06-10 13:36:04 -07006286
Christopher Tate136b1f92010-02-11 17:51:24 -08006287 if (force || mLastWin == null || !mLastWin.mToken.paused
6288 || !mLastWin.isVisibleLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 // If the current window has been paused, we aren't -really-
6290 // finished... so let the waiters still wait.
6291 mLastWin = null;
6292 mLastBinder = null;
6293 }
6294 mFinished = true;
6295 notifyAll();
6296 }
6297 }
6298
6299 private class KeyQ extends KeyInputQueue
6300 implements KeyInputQueue.FilterCallback {
6301 PowerManager.WakeLock mHoldingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07006302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006303 KeyQ() {
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006304 super(mContext, WindowManagerService.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006305 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
6306 mHoldingScreen = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
6307 "KEEP_SCREEN_ON_FLAG");
6308 mHoldingScreen.setReferenceCounted(false);
6309 }
6310
6311 @Override
6312 boolean preprocessEvent(InputDevice device, RawInputEvent event) {
6313 if (mPolicy.preprocessInputEventTq(event)) {
6314 return true;
6315 }
Romain Guy06882f82009-06-10 13:36:04 -07006316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 switch (event.type) {
6318 case RawInputEvent.EV_KEY: {
6319 // XXX begin hack
6320 if (DEBUG) {
6321 if (event.keycode == KeyEvent.KEYCODE_G) {
6322 if (event.value != 0) {
6323 // G down
6324 mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
6325 }
6326 return false;
6327 }
6328 if (event.keycode == KeyEvent.KEYCODE_D) {
6329 if (event.value != 0) {
6330 //dump();
6331 }
6332 return false;
6333 }
6334 }
6335 // XXX end hack
Romain Guy06882f82009-06-10 13:36:04 -07006336
Charles Mendis322591c2009-10-29 11:06:59 -07006337 boolean screenIsOff = !mPowerManager.isScreenOn();
6338 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
Romain Guy06882f82009-06-10 13:36:04 -07006340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006341 if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
6342 mPowerManager.goToSleep(event.when);
6343 }
6344
6345 if (screenIsOff) {
6346 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6347 }
6348 if (screenIsDim) {
6349 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6350 }
6351 if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
6352 mPowerManager.userActivity(event.when, false,
Michael Chane96440f2009-05-06 10:27:36 -07006353 LocalPowerManager.BUTTON_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006354 }
Romain Guy06882f82009-06-10 13:36:04 -07006355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006356 if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
6357 if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
6358 filterQueue(this);
6359 mKeyWaiter.appSwitchComing();
6360 }
6361 return true;
6362 } else {
6363 return false;
6364 }
6365 }
Romain Guy06882f82009-06-10 13:36:04 -07006366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 case RawInputEvent.EV_REL: {
Charles Mendis322591c2009-10-29 11:06:59 -07006368 boolean screenIsOff = !mPowerManager.isScreenOn();
6369 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 if (screenIsOff) {
6371 if (!mPolicy.isWakeRelMovementTq(event.deviceId,
6372 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006373 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 return false;
6375 }
6376 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6377 }
6378 if (screenIsDim) {
6379 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6380 }
6381 return true;
6382 }
Romain Guy06882f82009-06-10 13:36:04 -07006383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 case RawInputEvent.EV_ABS: {
Charles Mendis322591c2009-10-29 11:06:59 -07006385 boolean screenIsOff = !mPowerManager.isScreenOn();
6386 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006387 if (screenIsOff) {
6388 if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
6389 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006390 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 return false;
6392 }
6393 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6394 }
6395 if (screenIsDim) {
6396 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6397 }
6398 return true;
6399 }
Romain Guy06882f82009-06-10 13:36:04 -07006400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006401 default:
6402 return true;
6403 }
6404 }
6405
6406 public int filterEvent(QueuedEvent ev) {
6407 switch (ev.classType) {
6408 case RawInputEvent.CLASS_KEYBOARD:
6409 KeyEvent ke = (KeyEvent)ev.event;
6410 if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006411 Slog.w(TAG, "Dropping movement key during app switch: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006412 + ke.getKeyCode() + ", action=" + ke.getAction());
6413 return FILTER_REMOVE;
6414 }
6415 return FILTER_ABORT;
6416 default:
6417 return FILTER_KEEP;
6418 }
6419 }
Romain Guy06882f82009-06-10 13:36:04 -07006420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006421 /**
6422 * Must be called with the main window manager lock held.
6423 */
6424 void setHoldScreenLocked(boolean holding) {
6425 boolean state = mHoldingScreen.isHeld();
6426 if (holding != state) {
6427 if (holding) {
6428 mHoldingScreen.acquire();
6429 } else {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006430 mPolicy.screenOnStoppedLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006431 mHoldingScreen.release();
6432 }
6433 }
6434 }
Michael Chan53071d62009-05-13 17:29:48 -07006435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006436
6437 public boolean detectSafeMode() {
6438 mSafeMode = mPolicy.detectSafeMode();
6439 return mSafeMode;
6440 }
Romain Guy06882f82009-06-10 13:36:04 -07006441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006442 public void systemReady() {
6443 mPolicy.systemReady();
6444 }
Romain Guy06882f82009-06-10 13:36:04 -07006445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006446 private final class InputDispatcherThread extends Thread {
6447 // Time to wait when there is nothing to do: 9999 seconds.
6448 static final int LONG_WAIT=9999*1000;
6449
6450 public InputDispatcherThread() {
6451 super("InputDispatcher");
6452 }
Romain Guy06882f82009-06-10 13:36:04 -07006453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 @Override
6455 public void run() {
6456 while (true) {
6457 try {
6458 process();
6459 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006460 Slog.e(TAG, "Exception in input dispatcher", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006461 }
6462 }
6463 }
Romain Guy06882f82009-06-10 13:36:04 -07006464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 private void process() {
6466 android.os.Process.setThreadPriority(
6467 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -07006468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006469 // The last key event we saw
6470 KeyEvent lastKey = null;
6471
6472 // Last keydown time for auto-repeating keys
6473 long lastKeyTime = SystemClock.uptimeMillis();
6474 long nextKeyTime = lastKeyTime+LONG_WAIT;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006475 long downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006476
Romain Guy06882f82009-06-10 13:36:04 -07006477 // How many successive repeats we generated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 int keyRepeatCount = 0;
6479
6480 // Need to report that configuration has changed?
6481 boolean configChanged = false;
Romain Guy06882f82009-06-10 13:36:04 -07006482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006483 while (true) {
6484 long curTime = SystemClock.uptimeMillis();
6485
Joe Onorato8a9b2202010-02-26 18:56:32 -08006486 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487 TAG, "Waiting for next key: now=" + curTime
6488 + ", repeat @ " + nextKeyTime);
6489
6490 // Retrieve next event, waiting only as long as the next
6491 // repeat timeout. If the configuration has changed, then
6492 // don't wait at all -- we'll report the change as soon as
6493 // we have processed all events.
6494 QueuedEvent ev = mQueue.getEvent(
6495 (int)((!configChanged && curTime < nextKeyTime)
6496 ? (nextKeyTime-curTime) : 0));
6497
Joe Onorato8a9b2202010-02-26 18:56:32 -08006498 if (DEBUG_INPUT && ev != null) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006499 TAG, "Event: type=" + ev.classType + " data=" + ev.event);
6500
Michael Chan53071d62009-05-13 17:29:48 -07006501 if (MEASURE_LATENCY) {
6502 lt.sample("2 got event ", System.nanoTime() - ev.whenNano);
6503 }
6504
Mike Lockwood3d0ea722009-10-21 22:58:29 -04006505 if (lastKey != null && !mPolicy.allowKeyRepeat()) {
6506 // cancel key repeat at the request of the policy.
6507 lastKey = null;
6508 downTime = 0;
6509 lastKeyTime = curTime;
6510 nextKeyTime = curTime + LONG_WAIT;
6511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 try {
6513 if (ev != null) {
Michael Chan53071d62009-05-13 17:29:48 -07006514 curTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 int eventType;
6516 if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
6517 eventType = eventType((MotionEvent)ev.event);
6518 } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
6519 ev.classType == RawInputEvent.CLASS_TRACKBALL) {
6520 eventType = LocalPowerManager.BUTTON_EVENT;
6521 } else {
6522 eventType = LocalPowerManager.OTHER_EVENT;
6523 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006524 try {
Michael Chan53071d62009-05-13 17:29:48 -07006525 if ((curTime - mLastBatteryStatsCallTime)
Michael Chane96440f2009-05-06 10:27:36 -07006526 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
Michael Chan53071d62009-05-13 17:29:48 -07006527 mLastBatteryStatsCallTime = curTime;
Michael Chane96440f2009-05-06 10:27:36 -07006528 mBatteryStats.noteInputEvent();
6529 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006530 } catch (RemoteException e) {
6531 // Ignore
6532 }
Michael Chane10de972009-05-18 11:24:50 -07006533
Mike Lockwood5db42402009-11-30 14:51:51 -05006534 if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
6535 // do not wake screen in this case
6536 } else if (eventType != TOUCH_EVENT
Michael Chane10de972009-05-18 11:24:50 -07006537 && eventType != LONG_TOUCH_EVENT
6538 && eventType != CHEEK_EVENT) {
6539 mPowerManager.userActivity(curTime, false,
6540 eventType, false);
6541 } else if (mLastTouchEventType != eventType
6542 || (curTime - mLastUserActivityCallTime)
6543 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
6544 mLastUserActivityCallTime = curTime;
6545 mLastTouchEventType = eventType;
6546 mPowerManager.userActivity(curTime, false,
6547 eventType, false);
6548 }
6549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006550 switch (ev.classType) {
6551 case RawInputEvent.CLASS_KEYBOARD:
6552 KeyEvent ke = (KeyEvent)ev.event;
6553 if (ke.isDown()) {
6554 lastKey = ke;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006555 downTime = curTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 keyRepeatCount = 0;
6557 lastKeyTime = curTime;
6558 nextKeyTime = lastKeyTime
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006559 + ViewConfiguration.getLongPressTimeout();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006560 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 TAG, "Received key down: first repeat @ "
6562 + nextKeyTime);
6563 } else {
6564 lastKey = null;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006565 downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006566 // Arbitrary long timeout.
6567 lastKeyTime = curTime;
6568 nextKeyTime = curTime + LONG_WAIT;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006569 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006570 TAG, "Received key up: ignore repeat @ "
6571 + nextKeyTime);
6572 }
6573 dispatchKey((KeyEvent)ev.event, 0, 0);
6574 mQueue.recycleEvent(ev);
6575 break;
6576 case RawInputEvent.CLASS_TOUCHSCREEN:
Joe Onorato8a9b2202010-02-26 18:56:32 -08006577 //Slog.i(TAG, "Read next event " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006578 dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
6579 break;
6580 case RawInputEvent.CLASS_TRACKBALL:
6581 dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
6582 break;
6583 case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
6584 configChanged = true;
6585 break;
6586 default:
6587 mQueue.recycleEvent(ev);
6588 break;
6589 }
Romain Guy06882f82009-06-10 13:36:04 -07006590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 } else if (configChanged) {
6592 configChanged = false;
6593 sendNewConfiguration();
Romain Guy06882f82009-06-10 13:36:04 -07006594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 } else if (lastKey != null) {
6596 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07006597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 // Timeout occurred while key was down. If it is at or
6599 // past the key repeat time, dispatch the repeat.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006600 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 TAG, "Key timeout: repeat=" + nextKeyTime
6602 + ", now=" + curTime);
6603 if (curTime < nextKeyTime) {
6604 continue;
6605 }
Romain Guy06882f82009-06-10 13:36:04 -07006606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 lastKeyTime = nextKeyTime;
6608 nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
6609 keyRepeatCount++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006610 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 TAG, "Key repeat: count=" + keyRepeatCount
6612 + ", next @ " + nextKeyTime);
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006613 KeyEvent newEvent;
6614 if (downTime != 0 && (downTime
6615 + ViewConfiguration.getLongPressTimeout())
6616 <= curTime) {
6617 newEvent = KeyEvent.changeTimeRepeat(lastKey,
6618 curTime, keyRepeatCount,
6619 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
6620 downTime = 0;
6621 } else {
6622 newEvent = KeyEvent.changeTimeRepeat(lastKey,
6623 curTime, keyRepeatCount);
6624 }
6625 dispatchKey(newEvent, 0, 0);
Romain Guy06882f82009-06-10 13:36:04 -07006626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 } else {
6628 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07006629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 lastKeyTime = curTime;
6631 nextKeyTime = curTime + LONG_WAIT;
6632 }
Romain Guy06882f82009-06-10 13:36:04 -07006633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006635 Slog.e(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 "Input thread received uncaught exception: " + e, e);
6637 }
6638 }
6639 }
6640 }
6641
6642 // -------------------------------------------------------------
6643 // Client Session State
6644 // -------------------------------------------------------------
6645
6646 private final class Session extends IWindowSession.Stub
6647 implements IBinder.DeathRecipient {
6648 final IInputMethodClient mClient;
6649 final IInputContext mInputContext;
6650 final int mUid;
6651 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006652 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 SurfaceSession mSurfaceSession;
6654 int mNumWindow = 0;
6655 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 /**
6658 * Current pointer move event being dispatched to client window... must
6659 * hold key lock to access.
6660 */
6661 QueuedEvent mPendingPointerMove;
6662 WindowState mPendingPointerWindow;
Romain Guy06882f82009-06-10 13:36:04 -07006663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 /**
6665 * Current trackball move event being dispatched to client window... must
6666 * hold key lock to access.
6667 */
6668 QueuedEvent mPendingTrackballMove;
6669 WindowState mPendingTrackballWindow;
6670
6671 public Session(IInputMethodClient client, IInputContext inputContext) {
6672 mClient = client;
6673 mInputContext = inputContext;
6674 mUid = Binder.getCallingUid();
6675 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006676 StringBuilder sb = new StringBuilder();
6677 sb.append("Session{");
6678 sb.append(Integer.toHexString(System.identityHashCode(this)));
6679 sb.append(" uid ");
6680 sb.append(mUid);
6681 sb.append("}");
6682 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006684 synchronized (mWindowMap) {
6685 if (mInputMethodManager == null && mHaveInputMethods) {
6686 IBinder b = ServiceManager.getService(
6687 Context.INPUT_METHOD_SERVICE);
6688 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6689 }
6690 }
6691 long ident = Binder.clearCallingIdentity();
6692 try {
6693 // Note: it is safe to call in to the input method manager
6694 // here because we are not holding our lock.
6695 if (mInputMethodManager != null) {
6696 mInputMethodManager.addClient(client, inputContext,
6697 mUid, mPid);
6698 } else {
6699 client.setUsingInputMethod(false);
6700 }
6701 client.asBinder().linkToDeath(this, 0);
6702 } catch (RemoteException e) {
6703 // The caller has died, so we can just forget about this.
6704 try {
6705 if (mInputMethodManager != null) {
6706 mInputMethodManager.removeClient(client);
6707 }
6708 } catch (RemoteException ee) {
6709 }
6710 } finally {
6711 Binder.restoreCallingIdentity(ident);
6712 }
6713 }
Romain Guy06882f82009-06-10 13:36:04 -07006714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 @Override
6716 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6717 throws RemoteException {
6718 try {
6719 return super.onTransact(code, data, reply, flags);
6720 } catch (RuntimeException e) {
6721 // Log all 'real' exceptions thrown to the caller
6722 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006723 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 }
6725 throw e;
6726 }
6727 }
6728
6729 public void binderDied() {
6730 // Note: it is safe to call in to the input method manager
6731 // here because we are not holding our lock.
6732 try {
6733 if (mInputMethodManager != null) {
6734 mInputMethodManager.removeClient(mClient);
6735 }
6736 } catch (RemoteException e) {
6737 }
6738 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006739 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 mClientDead = true;
6741 killSessionLocked();
6742 }
6743 }
6744
6745 public int add(IWindow window, WindowManager.LayoutParams attrs,
6746 int viewVisibility, Rect outContentInsets) {
6747 return addWindow(this, window, attrs, viewVisibility, outContentInsets);
6748 }
Romain Guy06882f82009-06-10 13:36:04 -07006749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750 public void remove(IWindow window) {
6751 removeWindow(this, window);
6752 }
Romain Guy06882f82009-06-10 13:36:04 -07006753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6755 int requestedWidth, int requestedHeight, int viewFlags,
6756 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006757 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 return relayoutWindow(this, window, attrs,
6759 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006760 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 }
Romain Guy06882f82009-06-10 13:36:04 -07006762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006763 public void setTransparentRegion(IWindow window, Region region) {
6764 setTransparentRegionWindow(this, window, region);
6765 }
Romain Guy06882f82009-06-10 13:36:04 -07006766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006767 public void setInsets(IWindow window, int touchableInsets,
6768 Rect contentInsets, Rect visibleInsets) {
6769 setInsetsWindow(this, window, touchableInsets, contentInsets,
6770 visibleInsets);
6771 }
Romain Guy06882f82009-06-10 13:36:04 -07006772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6774 getWindowDisplayFrame(this, window, outDisplayFrame);
6775 }
Romain Guy06882f82009-06-10 13:36:04 -07006776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006778 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 TAG, "IWindow finishDrawing called for " + window);
6780 finishDrawingWindow(this, window);
6781 }
6782
6783 public void finishKey(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006784 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 TAG, "IWindow finishKey called for " + window);
6786 mKeyWaiter.finishedKey(this, window, false,
6787 KeyWaiter.RETURN_NOTHING);
6788 }
6789
6790 public MotionEvent getPendingPointerMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006791 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 TAG, "IWindow getPendingMotionEvent called for " + window);
6793 return mKeyWaiter.finishedKey(this, window, false,
6794 KeyWaiter.RETURN_PENDING_POINTER);
6795 }
Romain Guy06882f82009-06-10 13:36:04 -07006796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006797 public MotionEvent getPendingTrackballMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006798 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 TAG, "IWindow getPendingMotionEvent called for " + window);
6800 return mKeyWaiter.finishedKey(this, window, false,
6801 KeyWaiter.RETURN_PENDING_TRACKBALL);
6802 }
6803
6804 public void setInTouchMode(boolean mode) {
6805 synchronized(mWindowMap) {
6806 mInTouchMode = mode;
6807 }
6808 }
6809
6810 public boolean getInTouchMode() {
6811 synchronized(mWindowMap) {
6812 return mInTouchMode;
6813 }
6814 }
6815
6816 public boolean performHapticFeedback(IWindow window, int effectId,
6817 boolean always) {
6818 synchronized(mWindowMap) {
6819 long ident = Binder.clearCallingIdentity();
6820 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006821 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006822 windowForClientLocked(this, window, true),
6823 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 } finally {
6825 Binder.restoreCallingIdentity(ident);
6826 }
6827 }
6828 }
Romain Guy06882f82009-06-10 13:36:04 -07006829
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006830 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006831 synchronized(mWindowMap) {
6832 long ident = Binder.clearCallingIdentity();
6833 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006834 setWindowWallpaperPositionLocked(
6835 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006836 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006837 } finally {
6838 Binder.restoreCallingIdentity(ident);
6839 }
6840 }
6841 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006842
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006843 public void wallpaperOffsetsComplete(IBinder window) {
6844 WindowManagerService.this.wallpaperOffsetsComplete(window);
6845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006846
Dianne Hackborn75804932009-10-20 20:15:20 -07006847 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6848 int z, Bundle extras, boolean sync) {
6849 synchronized(mWindowMap) {
6850 long ident = Binder.clearCallingIdentity();
6851 try {
6852 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006853 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006854 action, x, y, z, extras, sync);
6855 } finally {
6856 Binder.restoreCallingIdentity(ident);
6857 }
6858 }
6859 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006860
Dianne Hackborn75804932009-10-20 20:15:20 -07006861 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6862 WindowManagerService.this.wallpaperCommandComplete(window, result);
6863 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006865 void windowAddedLocked() {
6866 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006867 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 TAG, "First window added to " + this + ", creating SurfaceSession");
6869 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006870 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006871 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 mSessions.add(this);
6873 }
6874 mNumWindow++;
6875 }
6876
6877 void windowRemovedLocked() {
6878 mNumWindow--;
6879 killSessionLocked();
6880 }
Romain Guy06882f82009-06-10 13:36:04 -07006881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 void killSessionLocked() {
6883 if (mNumWindow <= 0 && mClientDead) {
6884 mSessions.remove(this);
6885 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006886 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 TAG, "Last window removed from " + this
6888 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006889 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006890 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006891 try {
6892 mSurfaceSession.kill();
6893 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006894 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 + mSurfaceSession + " in session " + this
6896 + ": " + e.toString());
6897 }
6898 mSurfaceSession = null;
6899 }
6900 }
6901 }
Romain Guy06882f82009-06-10 13:36:04 -07006902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006904 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6905 pw.print(" mClientDead="); pw.print(mClientDead);
6906 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
6907 if (mPendingPointerWindow != null || mPendingPointerMove != null) {
6908 pw.print(prefix);
6909 pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
6910 pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
6911 }
6912 if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
6913 pw.print(prefix);
6914 pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
6915 pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
6916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006917 }
6918
6919 @Override
6920 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006921 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 }
6923 }
6924
6925 // -------------------------------------------------------------
6926 // Client Window State
6927 // -------------------------------------------------------------
6928
6929 private final class WindowState implements WindowManagerPolicy.WindowState {
6930 final Session mSession;
6931 final IWindow mClient;
6932 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006933 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006934 AppWindowToken mAppToken;
6935 AppWindowToken mTargetAppToken;
6936 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6937 final DeathRecipient mDeathRecipient;
6938 final WindowState mAttachedWindow;
6939 final ArrayList mChildWindows = new ArrayList();
6940 final int mBaseLayer;
6941 final int mSubLayer;
6942 final boolean mLayoutAttached;
6943 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006944 final boolean mIsWallpaper;
6945 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 int mViewVisibility;
6947 boolean mPolicyVisibility = true;
6948 boolean mPolicyVisibilityAfterAnim = true;
6949 boolean mAppFreezing;
6950 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006951 boolean mReportDestroySurface;
6952 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 boolean mAttachedHidden; // is our parent window hidden?
6954 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006955 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 int mRequestedWidth;
6957 int mRequestedHeight;
6958 int mLastRequestedWidth;
6959 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006960 int mLayer;
6961 int mAnimLayer;
6962 int mLastLayer;
6963 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006964 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006965 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966
6967 WindowState mNextOutsideTouch;
Romain Guy06882f82009-06-10 13:36:04 -07006968
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006969 int mLayoutSeq = -1;
6970
6971 Configuration mConfiguration = null;
6972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 // Actual frame shown on-screen (may be modified by animation)
6974 final Rect mShownFrame = new Rect();
6975 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006978 * Set when we have changed the size of the surface, to know that
6979 * we must tell them application to resize (and thus redraw itself).
6980 */
6981 boolean mSurfaceResized;
6982
6983 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 * Insets that determine the actually visible area
6985 */
6986 final Rect mVisibleInsets = new Rect();
6987 final Rect mLastVisibleInsets = new Rect();
6988 boolean mVisibleInsetsChanged;
6989
6990 /**
6991 * Insets that are covered by system windows
6992 */
6993 final Rect mContentInsets = new Rect();
6994 final Rect mLastContentInsets = new Rect();
6995 boolean mContentInsetsChanged;
6996
6997 /**
6998 * Set to true if we are waiting for this window to receive its
6999 * given internal insets before laying out other windows based on it.
7000 */
7001 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07007002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007003 /**
7004 * These are the content insets that were given during layout for
7005 * this window, to be applied to windows behind it.
7006 */
7007 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 /**
7010 * These are the visible insets that were given during layout for
7011 * this window, to be applied to windows behind it.
7012 */
7013 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 /**
7016 * Flag indicating whether the touchable region should be adjusted by
7017 * the visible insets; if false the area outside the visible insets is
7018 * NOT touchable, so we must use those to adjust the frame during hit
7019 * tests.
7020 */
7021 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07007022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 // Current transformation being applied.
7024 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
7025 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
7026 float mHScale=1, mVScale=1;
7027 float mLastHScale=1, mLastVScale=1;
7028 final Matrix mTmpMatrix = new Matrix();
7029
7030 // "Real" frame that the application sees.
7031 final Rect mFrame = new Rect();
7032 final Rect mLastFrame = new Rect();
7033
7034 final Rect mContainingFrame = new Rect();
7035 final Rect mDisplayFrame = new Rect();
7036 final Rect mContentFrame = new Rect();
7037 final Rect mVisibleFrame = new Rect();
7038
7039 float mShownAlpha = 1;
7040 float mAlpha = 1;
7041 float mLastAlpha = 1;
7042
7043 // Set to true if, when the window gets displayed, it should perform
7044 // an enter animation.
7045 boolean mEnterAnimationPending;
7046
7047 // Currently running animation.
7048 boolean mAnimating;
7049 boolean mLocalAnimating;
7050 Animation mAnimation;
7051 boolean mAnimationIsEntrance;
7052 boolean mHasTransformation;
7053 boolean mHasLocalTransformation;
7054 final Transformation mTransformation = new Transformation();
7055
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007056 // If a window showing a wallpaper: the requested offset for the
7057 // wallpaper; if a wallpaper window: the currently applied offset.
7058 float mWallpaperX = -1;
7059 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007060
7061 // If a window showing a wallpaper: what fraction of the offset
7062 // range corresponds to a full virtual screen.
7063 float mWallpaperXStep = -1;
7064 float mWallpaperYStep = -1;
7065
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007066 // Wallpaper windows: pixels offset based on above variables.
7067 int mXOffset;
7068 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007070 // This is set after IWindowSession.relayout() has been called at
7071 // least once for the window. It allows us to detect the situation
7072 // where we don't yet have a surface, but should have one soon, so
7073 // we can give the window focus before waiting for the relayout.
7074 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 // This is set after the Surface has been created but before the
7077 // window has been drawn. During this time the surface is hidden.
7078 boolean mDrawPending;
7079
7080 // This is set after the window has finished drawing for the first
7081 // time but before its surface is shown. The surface will be
7082 // displayed when the next layout is run.
7083 boolean mCommitDrawPending;
7084
7085 // This is set during the time after the window's drawing has been
7086 // committed, and before its surface is actually shown. It is used
7087 // to delay showing the surface until all windows in a token are ready
7088 // to be shown.
7089 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007091 // Set when the window has been shown in the screen the first time.
7092 boolean mHasDrawn;
7093
7094 // Currently running an exit animation?
7095 boolean mExiting;
7096
7097 // Currently on the mDestroySurface list?
7098 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100 // Completely remove from window manager after exit animation?
7101 boolean mRemoveOnExit;
7102
7103 // Set when the orientation is changing and this window has not yet
7104 // been updated for the new orientation.
7105 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 // Is this window now (or just being) removed?
7108 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007109
Dianne Hackborn16064f92010-03-25 00:47:24 -07007110 // For debugging, this is the last information given to the surface flinger.
7111 boolean mSurfaceShown;
7112 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7113 int mSurfaceLayer;
7114 float mSurfaceAlpha;
7115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 WindowState(Session s, IWindow c, WindowToken token,
7117 WindowState attachedWindow, WindowManager.LayoutParams a,
7118 int viewVisibility) {
7119 mSession = s;
7120 mClient = c;
7121 mToken = token;
7122 mAttrs.copyFrom(a);
7123 mViewVisibility = viewVisibility;
7124 DeathRecipient deathRecipient = new DeathRecipient();
7125 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007126 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 TAG, "Window " + this + " client=" + c.asBinder()
7128 + " token=" + token + " (" + mAttrs.token + ")");
7129 try {
7130 c.asBinder().linkToDeath(deathRecipient, 0);
7131 } catch (RemoteException e) {
7132 mDeathRecipient = null;
7133 mAttachedWindow = null;
7134 mLayoutAttached = false;
7135 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007136 mIsWallpaper = false;
7137 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 mBaseLayer = 0;
7139 mSubLayer = 0;
7140 return;
7141 }
7142 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7145 mAttrs.type <= LAST_SUB_WINDOW)) {
7146 // The multiplier here is to reserve space for multiple
7147 // windows in the same type layer.
7148 mBaseLayer = mPolicy.windowTypeToLayerLw(
7149 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7150 + TYPE_LAYER_OFFSET;
7151 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7152 mAttachedWindow = attachedWindow;
7153 mAttachedWindow.mChildWindows.add(this);
7154 mLayoutAttached = mAttrs.type !=
7155 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7156 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7157 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007158 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7159 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007160 } else {
7161 // The multiplier here is to reserve space for multiple
7162 // windows in the same type layer.
7163 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7164 * TYPE_LAYER_MULTIPLIER
7165 + TYPE_LAYER_OFFSET;
7166 mSubLayer = 0;
7167 mAttachedWindow = null;
7168 mLayoutAttached = false;
7169 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7170 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007171 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7172 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007173 }
7174
7175 WindowState appWin = this;
7176 while (appWin.mAttachedWindow != null) {
7177 appWin = mAttachedWindow;
7178 }
7179 WindowToken appToken = appWin.mToken;
7180 while (appToken.appWindowToken == null) {
7181 WindowToken parent = mTokenMap.get(appToken.token);
7182 if (parent == null || appToken == parent) {
7183 break;
7184 }
7185 appToken = parent;
7186 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007187 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 mAppToken = appToken.appWindowToken;
7189
7190 mSurface = null;
7191 mRequestedWidth = 0;
7192 mRequestedHeight = 0;
7193 mLastRequestedWidth = 0;
7194 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007195 mXOffset = 0;
7196 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007197 mLayer = 0;
7198 mAnimLayer = 0;
7199 mLastLayer = 0;
7200 }
7201
7202 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007203 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 TAG, "Attaching " + this + " token=" + mToken
7205 + ", list=" + mToken.windows);
7206 mSession.windowAddedLocked();
7207 }
7208
7209 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7210 mHaveFrame = true;
7211
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007212 final Rect container = mContainingFrame;
7213 container.set(pf);
7214
7215 final Rect display = mDisplayFrame;
7216 display.set(df);
7217
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007218 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007219 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007220 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7221 display.intersect(mCompatibleScreenFrame);
7222 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007223 }
7224
7225 final int pw = container.right - container.left;
7226 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007227
7228 int w,h;
7229 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7230 w = mAttrs.width < 0 ? pw : mAttrs.width;
7231 h = mAttrs.height< 0 ? ph : mAttrs.height;
7232 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007233 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7234 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007235 }
Romain Guy06882f82009-06-10 13:36:04 -07007236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 final Rect content = mContentFrame;
7238 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007240 final Rect visible = mVisibleFrame;
7241 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007244 final int fw = frame.width();
7245 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7248 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7249
7250 Gravity.apply(mAttrs.gravity, w, h, container,
7251 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7252 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7253
7254 //System.out.println("Out: " + mFrame);
7255
7256 // Now make sure the window fits in the overall display.
7257 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 // Make sure the content and visible frames are inside of the
7260 // final window frame.
7261 if (content.left < frame.left) content.left = frame.left;
7262 if (content.top < frame.top) content.top = frame.top;
7263 if (content.right > frame.right) content.right = frame.right;
7264 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7265 if (visible.left < frame.left) visible.left = frame.left;
7266 if (visible.top < frame.top) visible.top = frame.top;
7267 if (visible.right > frame.right) visible.right = frame.right;
7268 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 final Rect contentInsets = mContentInsets;
7271 contentInsets.left = content.left-frame.left;
7272 contentInsets.top = content.top-frame.top;
7273 contentInsets.right = frame.right-content.right;
7274 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 final Rect visibleInsets = mVisibleInsets;
7277 visibleInsets.left = visible.left-frame.left;
7278 visibleInsets.top = visible.top-frame.top;
7279 visibleInsets.right = frame.right-visible.right;
7280 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007281
Dianne Hackborn284ac932009-08-28 10:34:25 -07007282 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7283 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007284 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007285 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 if (localLOGV) {
7288 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7289 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007290 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 + mRequestedWidth + ", mRequestedheight="
7292 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7293 + "): frame=" + mFrame.toShortString()
7294 + " ci=" + contentInsets.toShortString()
7295 + " vi=" + visibleInsets.toShortString());
7296 //}
7297 }
7298 }
Romain Guy06882f82009-06-10 13:36:04 -07007299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007300 public Rect getFrameLw() {
7301 return mFrame;
7302 }
7303
7304 public Rect getShownFrameLw() {
7305 return mShownFrame;
7306 }
7307
7308 public Rect getDisplayFrameLw() {
7309 return mDisplayFrame;
7310 }
7311
7312 public Rect getContentFrameLw() {
7313 return mContentFrame;
7314 }
7315
7316 public Rect getVisibleFrameLw() {
7317 return mVisibleFrame;
7318 }
7319
7320 public boolean getGivenInsetsPendingLw() {
7321 return mGivenInsetsPending;
7322 }
7323
7324 public Rect getGivenContentInsetsLw() {
7325 return mGivenContentInsets;
7326 }
Romain Guy06882f82009-06-10 13:36:04 -07007327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007328 public Rect getGivenVisibleInsetsLw() {
7329 return mGivenVisibleInsets;
7330 }
Romain Guy06882f82009-06-10 13:36:04 -07007331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 public WindowManager.LayoutParams getAttrs() {
7333 return mAttrs;
7334 }
7335
7336 public int getSurfaceLayer() {
7337 return mLayer;
7338 }
Romain Guy06882f82009-06-10 13:36:04 -07007339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 public IApplicationToken getAppToken() {
7341 return mAppToken != null ? mAppToken.appToken : null;
7342 }
7343
7344 public boolean hasAppShownWindows() {
7345 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7346 }
7347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007348 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007349 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007350 TAG, "Setting animation in " + this + ": " + anim);
7351 mAnimating = false;
7352 mLocalAnimating = false;
7353 mAnimation = anim;
7354 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7355 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7356 }
7357
7358 public void clearAnimation() {
7359 if (mAnimation != null) {
7360 mAnimating = true;
7361 mLocalAnimating = false;
7362 mAnimation = null;
7363 }
7364 }
Romain Guy06882f82009-06-10 13:36:04 -07007365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 Surface createSurfaceLocked() {
7367 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007368 mReportDestroySurface = false;
7369 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007370 mDrawPending = true;
7371 mCommitDrawPending = false;
7372 mReadyToShow = false;
7373 if (mAppToken != null) {
7374 mAppToken.allDrawn = false;
7375 }
7376
7377 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07007378 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 flags |= Surface.PUSH_BUFFERS;
7380 }
7381
7382 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7383 flags |= Surface.SECURE;
7384 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007385 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 TAG, "Creating surface in session "
7387 + mSession.mSurfaceSession + " window " + this
7388 + " w=" + mFrame.width()
7389 + " h=" + mFrame.height() + " format="
7390 + mAttrs.format + " flags=" + flags);
7391
7392 int w = mFrame.width();
7393 int h = mFrame.height();
7394 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7395 // for a scaled surface, we always want the requested
7396 // size.
7397 w = mRequestedWidth;
7398 h = mRequestedHeight;
7399 }
7400
Romain Guy9825ec62009-10-01 00:58:09 -07007401 // Something is wrong and SurfaceFlinger will not like this,
7402 // try to revert to sane values
7403 if (w <= 0) w = 1;
7404 if (h <= 0) h = 1;
7405
Dianne Hackborn16064f92010-03-25 00:47:24 -07007406 mSurfaceShown = false;
7407 mSurfaceLayer = 0;
7408 mSurfaceAlpha = 1;
7409 mSurfaceX = 0;
7410 mSurfaceY = 0;
7411 mSurfaceW = w;
7412 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007413 try {
7414 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007415 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007416 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007418 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007419 + mSurface + " IN SESSION "
7420 + mSession.mSurfaceSession
7421 + ": pid=" + mSession.mPid + " format="
7422 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007423 + Integer.toHexString(flags)
7424 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007426 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 reclaimSomeSurfaceMemoryLocked(this, "create");
7428 return null;
7429 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007430 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 return null;
7432 }
Romain Guy06882f82009-06-10 13:36:04 -07007433
Joe Onorato8a9b2202010-02-26 18:56:32 -08007434 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 TAG, "Got surface: " + mSurface
7436 + ", set left=" + mFrame.left + " top=" + mFrame.top
7437 + ", animLayer=" + mAnimLayer);
7438 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007439 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007440 if (SHOW_TRANSACTIONS) logSurface(this,
7441 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7442 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7443 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 }
7445 Surface.openTransaction();
7446 try {
7447 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007448 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007449 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007450 mSurface.setPosition(mSurfaceX, mSurfaceY);
7451 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007453 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007454 mSurface.hide();
7455 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007456 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 mSurface.setFlags(Surface.SURFACE_DITHER,
7458 Surface.SURFACE_DITHER);
7459 }
7460 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007461 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7463 }
7464 mLastHidden = true;
7465 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007466 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007467 Surface.closeTransaction();
7468 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007469 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 TAG, "Created surface " + this);
7471 }
7472 return mSurface;
7473 }
Romain Guy06882f82009-06-10 13:36:04 -07007474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007475 void destroySurfaceLocked() {
7476 // Window is no longer on-screen, so can no longer receive
7477 // key events... if we were waiting for it to finish
7478 // handling a key event, the wait is over!
7479 mKeyWaiter.finishedKey(mSession, mClient, true,
7480 KeyWaiter.RETURN_NOTHING);
7481 mKeyWaiter.releasePendingPointerLocked(mSession);
7482 mKeyWaiter.releasePendingTrackballLocked(mSession);
7483
7484 if (mAppToken != null && this == mAppToken.startingWindow) {
7485 mAppToken.startingDisplayed = false;
7486 }
Romain Guy06882f82009-06-10 13:36:04 -07007487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007488 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007489 mDrawPending = false;
7490 mCommitDrawPending = false;
7491 mReadyToShow = false;
7492
7493 int i = mChildWindows.size();
7494 while (i > 0) {
7495 i--;
7496 WindowState c = (WindowState)mChildWindows.get(i);
7497 c.mAttachedHidden = true;
7498 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007499
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007500 if (mReportDestroySurface) {
7501 mReportDestroySurface = false;
7502 mSurfacePendingDestroy = true;
7503 try {
7504 mClient.dispatchGetNewSurface();
7505 // We'll really destroy on the next time around.
7506 return;
7507 } catch (RemoteException e) {
7508 }
7509 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007512 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007513 RuntimeException e = null;
7514 if (!HIDE_STACK_CRAWLS) {
7515 e = new RuntimeException();
7516 e.fillInStackTrace();
7517 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007518 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007519 + mSurface + ", session " + mSession, e);
7520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007522 RuntimeException e = null;
7523 if (!HIDE_STACK_CRAWLS) {
7524 e = new RuntimeException();
7525 e.fillInStackTrace();
7526 }
7527 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007529 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007530 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007531 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007532 + " surface " + mSurface + " session " + mSession
7533 + ": " + e.toString());
7534 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007535
Dianne Hackborn16064f92010-03-25 00:47:24 -07007536 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007537 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 }
7539 }
7540
7541 boolean finishDrawingLocked() {
7542 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007543 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007544 TAG, "finishDrawingLocked: " + mSurface);
7545 mCommitDrawPending = true;
7546 mDrawPending = false;
7547 return true;
7548 }
7549 return false;
7550 }
7551
7552 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007553 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007554 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007556 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 }
7558 mCommitDrawPending = false;
7559 mReadyToShow = true;
7560 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7561 final AppWindowToken atoken = mAppToken;
7562 if (atoken == null || atoken.allDrawn || starting) {
7563 performShowLocked();
7564 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007565 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 }
7567
7568 // This must be called while inside a transaction.
7569 boolean performShowLocked() {
7570 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007571 RuntimeException e = null;
7572 if (!HIDE_STACK_CRAWLS) {
7573 e = new RuntimeException();
7574 e.fillInStackTrace();
7575 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007576 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007577 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7578 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7579 }
7580 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007581 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7582 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007583 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007584 + " during animation: policyVis=" + mPolicyVisibility
7585 + " attHidden=" + mAttachedHidden
7586 + " tok.hiddenRequested="
7587 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007588 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 + (mAppToken != null ? mAppToken.hidden : false)
7590 + " animating=" + mAnimating
7591 + " tok animating="
7592 + (mAppToken != null ? mAppToken.animating : false));
7593 if (!showSurfaceRobustlyLocked(this)) {
7594 return false;
7595 }
7596 mLastAlpha = -1;
7597 mHasDrawn = true;
7598 mLastHidden = false;
7599 mReadyToShow = false;
7600 enableScreenIfNeededLocked();
7601
7602 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007604 int i = mChildWindows.size();
7605 while (i > 0) {
7606 i--;
7607 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007608 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007609 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007610 if (c.mSurface != null) {
7611 c.performShowLocked();
7612 // It hadn't been shown, which means layout not
7613 // performed on it, so now we want to make sure to
7614 // do a layout. If called from within the transaction
7615 // loop, this will cause it to restart with a new
7616 // layout.
7617 mLayoutNeeded = true;
7618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007619 }
7620 }
Romain Guy06882f82009-06-10 13:36:04 -07007621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 if (mAttrs.type != TYPE_APPLICATION_STARTING
7623 && mAppToken != null) {
7624 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007625
Dianne Hackborn248b1882009-09-16 16:46:44 -07007626 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007627 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007628 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007630 // If this initial window is animating, stop it -- we
7631 // will do an animation to reveal it from behind the
7632 // starting window, so there is no need for it to also
7633 // be doing its own stuff.
7634 if (mAnimation != null) {
7635 mAnimation = null;
7636 // Make sure we clean up the animation.
7637 mAnimating = true;
7638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007639 mFinishedStarting.add(mAppToken);
7640 mH.sendEmptyMessage(H.FINISHED_STARTING);
7641 }
7642 mAppToken.updateReportedVisibilityLocked();
7643 }
7644 }
7645 return true;
7646 }
Romain Guy06882f82009-06-10 13:36:04 -07007647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007648 // This must be called while inside a transaction. Returns true if
7649 // there is more animation to run.
7650 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007651 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007652 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007654 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7655 mHasTransformation = true;
7656 mHasLocalTransformation = true;
7657 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007658 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659 TAG, "Starting animation in " + this +
7660 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7661 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7662 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7663 mAnimation.setStartTime(currentTime);
7664 mLocalAnimating = true;
7665 mAnimating = true;
7666 }
7667 mTransformation.clear();
7668 final boolean more = mAnimation.getTransformation(
7669 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007670 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 TAG, "Stepped animation in " + this +
7672 ": more=" + more + ", xform=" + mTransformation);
7673 if (more) {
7674 // we're not done!
7675 return true;
7676 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007677 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007678 TAG, "Finished animation in " + this +
7679 " @ " + currentTime);
7680 mAnimation = null;
7681 //WindowManagerService.this.dump();
7682 }
7683 mHasLocalTransformation = false;
7684 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007685 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 // When our app token is animating, we kind-of pretend like
7687 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7688 // part of this check means that we will only do this if
7689 // our window is not currently exiting, or it is not
7690 // locally animating itself. The idea being that one that
7691 // is exiting and doing a local animation should be removed
7692 // once that animation is done.
7693 mAnimating = true;
7694 mHasTransformation = true;
7695 mTransformation.clear();
7696 return false;
7697 } else if (mHasTransformation) {
7698 // Little trick to get through the path below to act like
7699 // we have finished an animation.
7700 mAnimating = true;
7701 } else if (isAnimating()) {
7702 mAnimating = true;
7703 }
7704 } else if (mAnimation != null) {
7705 // If the display is frozen, and there is a pending animation,
7706 // clear it and make sure we run the cleanup code.
7707 mAnimating = true;
7708 mLocalAnimating = true;
7709 mAnimation = null;
7710 }
Romain Guy06882f82009-06-10 13:36:04 -07007711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007712 if (!mAnimating && !mLocalAnimating) {
7713 return false;
7714 }
7715
Joe Onorato8a9b2202010-02-26 18:56:32 -08007716 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007717 TAG, "Animation done in " + this + ": exiting=" + mExiting
7718 + ", reportedVisible="
7719 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 mAnimating = false;
7722 mLocalAnimating = false;
7723 mAnimation = null;
7724 mAnimLayer = mLayer;
7725 if (mIsImWindow) {
7726 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007727 } else if (mIsWallpaper) {
7728 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007729 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007730 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 + " anim layer: " + mAnimLayer);
7732 mHasTransformation = false;
7733 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007734 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7735 if (DEBUG_VISIBILITY) {
7736 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7737 + mPolicyVisibilityAfterAnim);
7738 }
7739 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7740 if (!mPolicyVisibility) {
7741 if (mCurrentFocus == this) {
7742 mFocusMayChange = true;
7743 }
7744 // Window is no longer visible -- make sure if we were waiting
7745 // for it to be displayed before enabling the display, that
7746 // we allow the display to be enabled now.
7747 enableScreenIfNeededLocked();
7748 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007750 mTransformation.clear();
7751 if (mHasDrawn
7752 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7753 && mAppToken != null
7754 && mAppToken.firstWindowDrawn
7755 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007756 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007757 + mToken + ": first real window done animating");
7758 mFinishedStarting.add(mAppToken);
7759 mH.sendEmptyMessage(H.FINISHED_STARTING);
7760 }
Romain Guy06882f82009-06-10 13:36:04 -07007761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007762 finishExit();
7763
7764 if (mAppToken != null) {
7765 mAppToken.updateReportedVisibilityLocked();
7766 }
7767
7768 return false;
7769 }
7770
7771 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007772 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 TAG, "finishExit in " + this
7774 + ": exiting=" + mExiting
7775 + " remove=" + mRemoveOnExit
7776 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 final int N = mChildWindows.size();
7779 for (int i=0; i<N; i++) {
7780 ((WindowState)mChildWindows.get(i)).finishExit();
7781 }
Romain Guy06882f82009-06-10 13:36:04 -07007782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007783 if (!mExiting) {
7784 return;
7785 }
Romain Guy06882f82009-06-10 13:36:04 -07007786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007787 if (isWindowAnimating()) {
7788 return;
7789 }
7790
Joe Onorato8a9b2202010-02-26 18:56:32 -08007791 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007792 TAG, "Exit animation finished in " + this
7793 + ": remove=" + mRemoveOnExit);
7794 if (mSurface != null) {
7795 mDestroySurface.add(this);
7796 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007797 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007798 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 try {
7800 mSurface.hide();
7801 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007802 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007803 }
7804 mLastHidden = true;
7805 mKeyWaiter.releasePendingPointerLocked(mSession);
7806 }
7807 mExiting = false;
7808 if (mRemoveOnExit) {
7809 mPendingRemove.add(this);
7810 mRemoveOnExit = false;
7811 }
7812 }
Romain Guy06882f82009-06-10 13:36:04 -07007813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7815 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7816 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7817 if (dtdx < -.000001f || dtdx > .000001f) return false;
7818 if (dsdy < -.000001f || dsdy > .000001f) return false;
7819 return true;
7820 }
Romain Guy06882f82009-06-10 13:36:04 -07007821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007822 void computeShownFrameLocked() {
7823 final boolean selfTransformation = mHasLocalTransformation;
7824 Transformation attachedTransformation =
7825 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7826 ? mAttachedWindow.mTransformation : null;
7827 Transformation appTransformation =
7828 (mAppToken != null && mAppToken.hasTransformation)
7829 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007830
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007831 // Wallpapers are animated based on the "real" window they
7832 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007833 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007834 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007835 if (mWallpaperTarget.mHasLocalTransformation &&
7836 mWallpaperTarget.mAnimation != null &&
7837 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007838 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007839 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007840 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007841 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007842 }
7843 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007844 mWallpaperTarget.mAppToken.hasTransformation &&
7845 mWallpaperTarget.mAppToken.animation != null &&
7846 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007847 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007848 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007849 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007850 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007851 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007852 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007854 if (selfTransformation || attachedTransformation != null
7855 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007856 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 final Rect frame = mFrame;
7858 final float tmpFloats[] = mTmpFloats;
7859 final Matrix tmpMatrix = mTmpMatrix;
7860
7861 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007862 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007863 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007864 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007866 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007868 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 }
7870 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007871 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007872 }
7873
7874 // "convert" it into SurfaceFlinger's format
7875 // (a 2x2 matrix + an offset)
7876 // Here we must not transform the position of the surface
7877 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007878 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007880 tmpMatrix.getValues(tmpFloats);
7881 mDsDx = tmpFloats[Matrix.MSCALE_X];
7882 mDtDx = tmpFloats[Matrix.MSKEW_X];
7883 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7884 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007885 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7886 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 int w = frame.width();
7888 int h = frame.height();
7889 mShownFrame.set(x, y, x+w, y+h);
7890
7891 // Now set the alpha... but because our current hardware
7892 // can't do alpha transformation on a non-opaque surface,
7893 // turn it off if we are running an animation that is also
7894 // transforming since it is more important to have that
7895 // animation be smooth.
7896 mShownAlpha = mAlpha;
7897 if (!mLimitedAlphaCompositing
7898 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7899 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7900 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007901 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007902 if (selfTransformation) {
7903 mShownAlpha *= mTransformation.getAlpha();
7904 }
7905 if (attachedTransformation != null) {
7906 mShownAlpha *= attachedTransformation.getAlpha();
7907 }
7908 if (appTransformation != null) {
7909 mShownAlpha *= appTransformation.getAlpha();
7910 }
7911 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007912 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007913 }
Romain Guy06882f82009-06-10 13:36:04 -07007914
Joe Onorato8a9b2202010-02-26 18:56:32 -08007915 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007916 TAG, "Continuing animation in " + this +
7917 ": " + mShownFrame +
7918 ", alpha=" + mTransformation.getAlpha());
7919 return;
7920 }
Romain Guy06882f82009-06-10 13:36:04 -07007921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007922 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007923 if (mXOffset != 0 || mYOffset != 0) {
7924 mShownFrame.offset(mXOffset, mYOffset);
7925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007926 mShownAlpha = mAlpha;
7927 mDsDx = 1;
7928 mDtDx = 0;
7929 mDsDy = 0;
7930 mDtDy = 1;
7931 }
Romain Guy06882f82009-06-10 13:36:04 -07007932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 /**
7934 * Is this window visible? It is not visible if there is no
7935 * surface, or we are in the process of running an exit animation
7936 * that will remove the surface, or its app token has been hidden.
7937 */
7938 public boolean isVisibleLw() {
7939 final AppWindowToken atoken = mAppToken;
7940 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7941 && (atoken == null || !atoken.hiddenRequested)
7942 && !mExiting && !mDestroying;
7943 }
7944
7945 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007946 * Like {@link #isVisibleLw}, but also counts a window that is currently
7947 * "hidden" behind the keyguard as visible. This allows us to apply
7948 * things like window flags that impact the keyguard.
7949 * XXX I am starting to think we need to have ANOTHER visibility flag
7950 * for this "hidden behind keyguard" state rather than overloading
7951 * mPolicyVisibility. Ungh.
7952 */
7953 public boolean isVisibleOrBehindKeyguardLw() {
7954 final AppWindowToken atoken = mAppToken;
7955 return mSurface != null && !mAttachedHidden
7956 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackborn5943c202010-04-12 21:36:49 -07007957 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending))
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007958 && !mExiting && !mDestroying;
7959 }
7960
7961 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962 * Is this window visible, ignoring its app token? It is not visible
7963 * if there is no surface, or we are in the process of running an exit animation
7964 * that will remove the surface.
7965 */
7966 public boolean isWinVisibleLw() {
7967 final AppWindowToken atoken = mAppToken;
7968 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7969 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7970 && !mExiting && !mDestroying;
7971 }
7972
7973 /**
7974 * The same as isVisible(), but follows the current hidden state of
7975 * the associated app token, not the pending requested hidden state.
7976 */
7977 boolean isVisibleNow() {
7978 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007979 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980 }
7981
7982 /**
7983 * Same as isVisible(), but we also count it as visible between the
7984 * call to IWindowSession.add() and the first relayout().
7985 */
7986 boolean isVisibleOrAdding() {
7987 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007988 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7990 && mPolicyVisibility && !mAttachedHidden
7991 && (atoken == null || !atoken.hiddenRequested)
7992 && !mExiting && !mDestroying;
7993 }
7994
7995 /**
7996 * Is this window currently on-screen? It is on-screen either if it
7997 * is visible or it is currently running an animation before no longer
7998 * being visible.
7999 */
8000 boolean isOnScreen() {
8001 final AppWindowToken atoken = mAppToken;
8002 if (atoken != null) {
8003 return mSurface != null && mPolicyVisibility && !mDestroying
8004 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008005 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 } else {
8007 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008008 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 }
8010 }
Romain Guy06882f82009-06-10 13:36:04 -07008011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 /**
8013 * Like isOnScreen(), but we don't return true if the window is part
8014 * of a transition that has not yet been started.
8015 */
8016 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008017 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008018 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008019 return false;
8020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008021 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008022 final boolean animating = atoken != null
8023 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008025 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8026 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008027 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 }
8029
8030 /** Is the window or its container currently animating? */
8031 boolean isAnimating() {
8032 final WindowState attached = mAttachedWindow;
8033 final AppWindowToken atoken = mAppToken;
8034 return mAnimation != null
8035 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008036 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 (atoken.animation != null
8038 || atoken.inPendingTransaction));
8039 }
8040
8041 /** Is this window currently animating? */
8042 boolean isWindowAnimating() {
8043 return mAnimation != null;
8044 }
8045
8046 /**
8047 * Like isOnScreen, but returns false if the surface hasn't yet
8048 * been drawn.
8049 */
8050 public boolean isDisplayedLw() {
8051 final AppWindowToken atoken = mAppToken;
8052 return mSurface != null && mPolicyVisibility && !mDestroying
8053 && !mDrawPending && !mCommitDrawPending
8054 && ((!mAttachedHidden &&
8055 (atoken == null || !atoken.hiddenRequested))
8056 || mAnimating);
8057 }
8058
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008059 /**
8060 * Returns true if the window has a surface that it has drawn a
Dianne Hackborn5943c202010-04-12 21:36:49 -07008061 * complete UI in to. Note that this returns true if the orientation
8062 * is changing even if the window hasn't redrawn because we don't want
8063 * to stop things from executing during that time.
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008064 */
8065 public boolean isDrawnLw() {
8066 final AppWindowToken atoken = mAppToken;
8067 return mSurface != null && !mDestroying
Dianne Hackborn5943c202010-04-12 21:36:49 -07008068 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending));
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008069 }
8070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 public boolean fillsScreenLw(int screenWidth, int screenHeight,
8072 boolean shownFrame, boolean onlyOpaque) {
8073 if (mSurface == null) {
8074 return false;
8075 }
8076 if (mAppToken != null && !mAppToken.appFullscreen) {
8077 return false;
8078 }
8079 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
8080 return false;
8081 }
8082 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008083
8084 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
8085 return frame.left <= mCompatibleScreenFrame.left &&
8086 frame.top <= mCompatibleScreenFrame.top &&
8087 frame.right >= mCompatibleScreenFrame.right &&
8088 frame.bottom >= mCompatibleScreenFrame.bottom;
8089 } else {
8090 return frame.left <= 0 && frame.top <= 0
8091 && frame.right >= screenWidth
8092 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 }
Romain Guy06882f82009-06-10 13:36:04 -07008095
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008096 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008097 * Return true if the window is opaque and fully drawn. This indicates
8098 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008099 */
8100 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008101 return (mAttrs.format == PixelFormat.OPAQUE
8102 || mAttrs.type == TYPE_WALLPAPER)
8103 && mSurface != null && mAnimation == null
8104 && (mAppToken == null || mAppToken.animation == null)
8105 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008106 }
8107
8108 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8109 return
8110 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008111 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8112 // only if it's visible
8113 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008114 // and only if the application fills the compatible screen
8115 mFrame.left <= mCompatibleScreenFrame.left &&
8116 mFrame.top <= mCompatibleScreenFrame.top &&
8117 mFrame.right >= mCompatibleScreenFrame.right &&
8118 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008119 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008120 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008121 }
8122
8123 boolean isFullscreen(int screenWidth, int screenHeight) {
8124 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008125 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008126 }
8127
8128 void removeLocked() {
8129 if (mAttachedWindow != null) {
8130 mAttachedWindow.mChildWindows.remove(this);
8131 }
8132 destroySurfaceLocked();
8133 mSession.windowRemovedLocked();
8134 try {
8135 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8136 } catch (RuntimeException e) {
8137 // Ignore if it has already been removed (usually because
8138 // we are doing this as part of processing a death note.)
8139 }
8140 }
8141
8142 private class DeathRecipient implements IBinder.DeathRecipient {
8143 public void binderDied() {
8144 try {
8145 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008146 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008147 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 if (win != null) {
8149 removeWindowLocked(mSession, win);
8150 }
8151 }
8152 } catch (IllegalArgumentException ex) {
8153 // This will happen if the window has already been
8154 // removed.
8155 }
8156 }
8157 }
8158
8159 /** Returns true if this window desires key events. */
8160 public final boolean canReceiveKeys() {
8161 return isVisibleOrAdding()
8162 && (mViewVisibility == View.VISIBLE)
8163 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8164 }
8165
8166 public boolean hasDrawnLw() {
8167 return mHasDrawn;
8168 }
8169
8170 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008171 return showLw(doAnimation, true);
8172 }
8173
8174 boolean showLw(boolean doAnimation, boolean requestAnim) {
8175 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8176 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008178 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008179 if (doAnimation) {
8180 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8181 + mPolicyVisibility + " mAnimation=" + mAnimation);
8182 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8183 doAnimation = false;
8184 } else if (mPolicyVisibility && mAnimation == null) {
8185 // Check for the case where we are currently visible and
8186 // not animating; we do not want to do animation at such a
8187 // point to become visible when we already are.
8188 doAnimation = false;
8189 }
8190 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008191 mPolicyVisibility = true;
8192 mPolicyVisibilityAfterAnim = true;
8193 if (doAnimation) {
8194 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8195 }
8196 if (requestAnim) {
8197 requestAnimationLocked(0);
8198 }
8199 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008200 }
8201
8202 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008203 return hideLw(doAnimation, true);
8204 }
8205
8206 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008207 if (doAnimation) {
8208 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8209 doAnimation = false;
8210 }
8211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8213 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008214 if (!current) {
8215 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008217 if (doAnimation) {
8218 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8219 if (mAnimation == null) {
8220 doAnimation = false;
8221 }
8222 }
8223 if (doAnimation) {
8224 mPolicyVisibilityAfterAnim = false;
8225 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008226 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008227 mPolicyVisibilityAfterAnim = false;
8228 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008229 // Window is no longer visible -- make sure if we were waiting
8230 // for it to be displayed before enabling the display, that
8231 // we allow the display to be enabled now.
8232 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008233 if (mCurrentFocus == this) {
8234 mFocusMayChange = true;
8235 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008236 }
8237 if (requestAnim) {
8238 requestAnimationLocked(0);
8239 }
8240 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 }
8242
8243 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008244 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8245 pw.print(" mClient="); pw.println(mClient.asBinder());
8246 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8247 if (mAttachedWindow != null || mLayoutAttached) {
8248 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8249 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8250 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008251 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8252 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8253 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008254 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8255 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008256 }
8257 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8258 pw.print(" mSubLayer="); pw.print(mSubLayer);
8259 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8260 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8261 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8262 pw.print("="); pw.print(mAnimLayer);
8263 pw.print(" mLastLayer="); pw.println(mLastLayer);
8264 if (mSurface != null) {
8265 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008266 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8267 pw.print(" layer="); pw.print(mSurfaceLayer);
8268 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8269 pw.print(" rect=("); pw.print(mSurfaceX);
8270 pw.print(","); pw.print(mSurfaceY);
8271 pw.print(") "); pw.print(mSurfaceW);
8272 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008273 }
8274 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8275 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8276 if (mAppToken != null) {
8277 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8278 }
8279 if (mTargetAppToken != null) {
8280 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8281 }
8282 pw.print(prefix); pw.print("mViewVisibility=0x");
8283 pw.print(Integer.toHexString(mViewVisibility));
8284 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008285 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8286 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008287 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8288 pw.print(prefix); pw.print("mPolicyVisibility=");
8289 pw.print(mPolicyVisibility);
8290 pw.print(" mPolicyVisibilityAfterAnim=");
8291 pw.print(mPolicyVisibilityAfterAnim);
8292 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8293 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008294 if (!mRelayoutCalled) {
8295 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8296 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008297 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008298 pw.print(" h="); pw.print(mRequestedHeight);
8299 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008300 if (mXOffset != 0 || mYOffset != 0) {
8301 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8302 pw.print(" y="); pw.println(mYOffset);
8303 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008304 pw.print(prefix); pw.print("mGivenContentInsets=");
8305 mGivenContentInsets.printShortString(pw);
8306 pw.print(" mGivenVisibleInsets=");
8307 mGivenVisibleInsets.printShortString(pw);
8308 pw.println();
8309 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8310 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8311 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8312 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008313 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008314 pw.print(prefix); pw.print("mShownFrame=");
8315 mShownFrame.printShortString(pw);
8316 pw.print(" last="); mLastShownFrame.printShortString(pw);
8317 pw.println();
8318 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8319 pw.print(" last="); mLastFrame.printShortString(pw);
8320 pw.println();
8321 pw.print(prefix); pw.print("mContainingFrame=");
8322 mContainingFrame.printShortString(pw);
8323 pw.print(" mDisplayFrame=");
8324 mDisplayFrame.printShortString(pw);
8325 pw.println();
8326 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8327 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8328 pw.println();
8329 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8330 pw.print(" last="); mLastContentInsets.printShortString(pw);
8331 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8332 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8333 pw.println();
8334 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8335 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8336 pw.print(" mAlpha="); pw.print(mAlpha);
8337 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8338 }
8339 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8340 || mAnimation != null) {
8341 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8342 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8343 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8344 pw.print(" mAnimation="); pw.println(mAnimation);
8345 }
8346 if (mHasTransformation || mHasLocalTransformation) {
8347 pw.print(prefix); pw.print("XForm: has=");
8348 pw.print(mHasTransformation);
8349 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8350 pw.print(" "); mTransformation.printShortString(pw);
8351 pw.println();
8352 }
8353 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8354 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8355 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8356 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8357 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8358 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8359 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8360 pw.print(" mDestroying="); pw.print(mDestroying);
8361 pw.print(" mRemoved="); pw.println(mRemoved);
8362 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008363 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008364 pw.print(prefix); pw.print("mOrientationChanging=");
8365 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008366 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8367 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008368 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008369 if (mHScale != 1 || mVScale != 1) {
8370 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8371 pw.print(" mVScale="); pw.println(mVScale);
8372 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008373 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008374 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8375 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8376 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008377 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8378 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8379 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008381 }
8382
8383 @Override
8384 public String toString() {
8385 return "Window{"
8386 + Integer.toHexString(System.identityHashCode(this))
8387 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
8388 }
8389 }
Romain Guy06882f82009-06-10 13:36:04 -07008390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 // -------------------------------------------------------------
8392 // Window Token State
8393 // -------------------------------------------------------------
8394
8395 class WindowToken {
8396 // The actual token.
8397 final IBinder token;
8398
8399 // The type of window this token is for, as per WindowManager.LayoutParams.
8400 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 // Set if this token was explicitly added by a client, so should
8403 // not be removed when all windows are removed.
8404 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008405
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008406 // For printing.
8407 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008409 // If this is an AppWindowToken, this is non-null.
8410 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412 // All of the windows associated with this token.
8413 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8414
8415 // Is key dispatching paused for this token?
8416 boolean paused = false;
8417
8418 // Should this token's windows be hidden?
8419 boolean hidden;
8420
8421 // Temporary for finding which tokens no longer have visible windows.
8422 boolean hasVisible;
8423
Dianne Hackborna8f60182009-09-01 19:01:50 -07008424 // Set to true when this token is in a pending transaction where it
8425 // will be shown.
8426 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008427
Dianne Hackborna8f60182009-09-01 19:01:50 -07008428 // Set to true when this token is in a pending transaction where it
8429 // will be hidden.
8430 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008431
Dianne Hackborna8f60182009-09-01 19:01:50 -07008432 // Set to true when this token is in a pending transaction where its
8433 // windows will be put to the bottom of the list.
8434 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008435
Dianne Hackborna8f60182009-09-01 19:01:50 -07008436 // Set to true when this token is in a pending transaction where its
8437 // windows will be put to the top of the list.
8438 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008440 WindowToken(IBinder _token, int type, boolean _explicit) {
8441 token = _token;
8442 windowType = type;
8443 explicit = _explicit;
8444 }
8445
8446 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008447 pw.print(prefix); pw.print("token="); pw.println(token);
8448 pw.print(prefix); pw.print("windows="); pw.println(windows);
8449 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8450 pw.print(" hidden="); pw.print(hidden);
8451 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008452 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8453 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8454 pw.print(" waitingToHide="); pw.print(waitingToHide);
8455 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8456 pw.print(" sendingToTop="); pw.println(sendingToTop);
8457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458 }
8459
8460 @Override
8461 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008462 if (stringName == null) {
8463 StringBuilder sb = new StringBuilder();
8464 sb.append("WindowToken{");
8465 sb.append(Integer.toHexString(System.identityHashCode(this)));
8466 sb.append(" token="); sb.append(token); sb.append('}');
8467 stringName = sb.toString();
8468 }
8469 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008470 }
8471 };
8472
8473 class AppWindowToken extends WindowToken {
8474 // Non-null only for application tokens.
8475 final IApplicationToken appToken;
8476
8477 // All of the windows and child windows that are included in this
8478 // application token. Note this list is NOT sorted!
8479 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8480
8481 int groupId = -1;
8482 boolean appFullscreen;
8483 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Romain Guy06882f82009-06-10 13:36:04 -07008484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 // These are used for determining when all windows associated with
8486 // an activity have been drawn, so they can be made visible together
8487 // at the same time.
8488 int lastTransactionSequence = mTransactionSequence-1;
8489 int numInterestingWindows;
8490 int numDrawnWindows;
8491 boolean inPendingTransaction;
8492 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008494 // Is this token going to be hidden in a little while? If so, it
8495 // won't be taken into account for setting the screen orientation.
8496 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008498 // Is this window's surface needed? This is almost like hidden, except
8499 // it will sometimes be true a little earlier: when the token has
8500 // been shown, but is still waiting for its app transition to execute
8501 // before making its windows shown.
8502 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 // Have we told the window clients to hide themselves?
8505 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507 // Last visibility state we reported to the app token.
8508 boolean reportedVisible;
8509
8510 // Set to true when the token has been removed from the window mgr.
8511 boolean removed;
8512
8513 // Have we been asked to have this token keep the screen frozen?
8514 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008516 boolean animating;
8517 Animation animation;
8518 boolean hasTransformation;
8519 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 // Offset to the window of all layers in the token, for use by
8522 // AppWindowToken animations.
8523 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 // Information about an application starting window if displayed.
8526 StartingData startingData;
8527 WindowState startingWindow;
8528 View startingView;
8529 boolean startingDisplayed;
8530 boolean startingMoved;
8531 boolean firstWindowDrawn;
8532
8533 AppWindowToken(IApplicationToken _token) {
8534 super(_token.asBinder(),
8535 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8536 appWindowToken = this;
8537 appToken = _token;
8538 }
Romain Guy06882f82009-06-10 13:36:04 -07008539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008540 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008541 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008542 TAG, "Setting animation in " + this + ": " + anim);
8543 animation = anim;
8544 animating = false;
8545 anim.restrictDuration(MAX_ANIMATION_DURATION);
8546 anim.scaleCurrentDuration(mTransitionAnimationScale);
8547 int zorder = anim.getZAdjustment();
8548 int adj = 0;
8549 if (zorder == Animation.ZORDER_TOP) {
8550 adj = TYPE_LAYER_OFFSET;
8551 } else if (zorder == Animation.ZORDER_BOTTOM) {
8552 adj = -TYPE_LAYER_OFFSET;
8553 }
Romain Guy06882f82009-06-10 13:36:04 -07008554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 if (animLayerAdjustment != adj) {
8556 animLayerAdjustment = adj;
8557 updateLayers();
8558 }
8559 }
Romain Guy06882f82009-06-10 13:36:04 -07008560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008561 public void setDummyAnimation() {
8562 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008563 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008564 TAG, "Setting dummy animation in " + this);
8565 animation = sDummyAnimation;
8566 }
8567 }
8568
8569 public void clearAnimation() {
8570 if (animation != null) {
8571 animation = null;
8572 animating = true;
8573 }
8574 }
Romain Guy06882f82009-06-10 13:36:04 -07008575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 void updateLayers() {
8577 final int N = allAppWindows.size();
8578 final int adj = animLayerAdjustment;
8579 for (int i=0; i<N; i++) {
8580 WindowState w = allAppWindows.get(i);
8581 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008582 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008583 + w.mAnimLayer);
8584 if (w == mInputMethodTarget) {
8585 setInputMethodAnimLayerAdjustment(adj);
8586 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008587 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008588 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 }
8591 }
Romain Guy06882f82009-06-10 13:36:04 -07008592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 void sendAppVisibilityToClients() {
8594 final int N = allAppWindows.size();
8595 for (int i=0; i<N; i++) {
8596 WindowState win = allAppWindows.get(i);
8597 if (win == startingWindow && clientHidden) {
8598 // Don't hide the starting window.
8599 continue;
8600 }
8601 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008602 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008603 "Setting visibility of " + win + ": " + (!clientHidden));
8604 win.mClient.dispatchAppVisibility(!clientHidden);
8605 } catch (RemoteException e) {
8606 }
8607 }
8608 }
Romain Guy06882f82009-06-10 13:36:04 -07008609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 void showAllWindowsLocked() {
8611 final int NW = allAppWindows.size();
8612 for (int i=0; i<NW; i++) {
8613 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008614 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 "performing show on: " + w);
8616 w.performShowLocked();
8617 }
8618 }
Romain Guy06882f82009-06-10 13:36:04 -07008619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008620 // This must be called while inside a transaction.
8621 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008622 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008623 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008625 if (animation == sDummyAnimation) {
8626 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008627 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 // when it is really time to animate, this will be set to
8629 // a real animation and the next call will execute normally.
8630 return false;
8631 }
Romain Guy06882f82009-06-10 13:36:04 -07008632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8634 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008635 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008636 TAG, "Starting animation in " + this +
8637 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8638 + " scale=" + mTransitionAnimationScale
8639 + " allDrawn=" + allDrawn + " animating=" + animating);
8640 animation.initialize(dw, dh, dw, dh);
8641 animation.setStartTime(currentTime);
8642 animating = true;
8643 }
8644 transformation.clear();
8645 final boolean more = animation.getTransformation(
8646 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008647 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008648 TAG, "Stepped animation in " + this +
8649 ": more=" + more + ", xform=" + transformation);
8650 if (more) {
8651 // we're done!
8652 hasTransformation = true;
8653 return true;
8654 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008655 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 TAG, "Finished animation in " + this +
8657 " @ " + currentTime);
8658 animation = null;
8659 }
8660 } else if (animation != null) {
8661 // If the display is frozen, and there is a pending animation,
8662 // clear it and make sure we run the cleanup code.
8663 animating = true;
8664 animation = null;
8665 }
8666
8667 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669 if (!animating) {
8670 return false;
8671 }
8672
8673 clearAnimation();
8674 animating = false;
8675 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8676 moveInputMethodWindowsIfNeededLocked(true);
8677 }
Romain Guy06882f82009-06-10 13:36:04 -07008678
Joe Onorato8a9b2202010-02-26 18:56:32 -08008679 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 TAG, "Animation done in " + this
8681 + ": reportedVisible=" + reportedVisible);
8682
8683 transformation.clear();
8684 if (animLayerAdjustment != 0) {
8685 animLayerAdjustment = 0;
8686 updateLayers();
8687 }
Romain Guy06882f82009-06-10 13:36:04 -07008688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 final int N = windows.size();
8690 for (int i=0; i<N; i++) {
8691 ((WindowState)windows.get(i)).finishExit();
8692 }
8693 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008695 return false;
8696 }
8697
8698 void updateReportedVisibilityLocked() {
8699 if (appToken == null) {
8700 return;
8701 }
Romain Guy06882f82009-06-10 13:36:04 -07008702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008703 int numInteresting = 0;
8704 int numVisible = 0;
8705 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008706
Joe Onorato8a9b2202010-02-26 18:56:32 -08008707 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 final int N = allAppWindows.size();
8709 for (int i=0; i<N; i++) {
8710 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008711 if (win == startingWindow || win.mAppFreezing
8712 || win.mViewVisibility != View.VISIBLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008713 continue;
8714 }
8715 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008716 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008717 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008718 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008719 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008720 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008721 + " pv=" + win.mPolicyVisibility
8722 + " dp=" + win.mDrawPending
8723 + " cdp=" + win.mCommitDrawPending
8724 + " ah=" + win.mAttachedHidden
8725 + " th="
8726 + (win.mAppToken != null
8727 ? win.mAppToken.hiddenRequested : false)
8728 + " a=" + win.mAnimating);
8729 }
8730 }
8731 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008732 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 if (!win.isAnimating()) {
8734 numVisible++;
8735 }
8736 nowGone = false;
8737 } else if (win.isAnimating()) {
8738 nowGone = false;
8739 }
8740 }
Romain Guy06882f82009-06-10 13:36:04 -07008741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008743 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008744 + numInteresting + " visible=" + numVisible);
8745 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008746 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 TAG, "Visibility changed in " + this
8748 + ": vis=" + nowVisible);
8749 reportedVisible = nowVisible;
8750 Message m = mH.obtainMessage(
8751 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8752 nowVisible ? 1 : 0,
8753 nowGone ? 1 : 0,
8754 this);
8755 mH.sendMessage(m);
8756 }
8757 }
Romain Guy06882f82009-06-10 13:36:04 -07008758
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008759 WindowState findMainWindow() {
8760 int j = windows.size();
8761 while (j > 0) {
8762 j--;
8763 WindowState win = windows.get(j);
8764 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8765 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8766 return win;
8767 }
8768 }
8769 return null;
8770 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 void dump(PrintWriter pw, String prefix) {
8773 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008774 if (appToken != null) {
8775 pw.print(prefix); pw.println("app=true");
8776 }
8777 if (allAppWindows.size() > 0) {
8778 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8779 }
8780 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008781 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008782 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8783 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8784 pw.print(" clientHidden="); pw.print(clientHidden);
8785 pw.print(" willBeHidden="); pw.print(willBeHidden);
8786 pw.print(" reportedVisible="); pw.println(reportedVisible);
8787 if (paused || freezingScreen) {
8788 pw.print(prefix); pw.print("paused="); pw.print(paused);
8789 pw.print(" freezingScreen="); pw.println(freezingScreen);
8790 }
8791 if (numInterestingWindows != 0 || numDrawnWindows != 0
8792 || inPendingTransaction || allDrawn) {
8793 pw.print(prefix); pw.print("numInterestingWindows=");
8794 pw.print(numInterestingWindows);
8795 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8796 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8797 pw.print(" allDrawn="); pw.println(allDrawn);
8798 }
8799 if (animating || animation != null) {
8800 pw.print(prefix); pw.print("animating="); pw.print(animating);
8801 pw.print(" animation="); pw.println(animation);
8802 }
8803 if (animLayerAdjustment != 0) {
8804 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8805 }
8806 if (hasTransformation) {
8807 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8808 pw.print(" transformation="); transformation.printShortString(pw);
8809 pw.println();
8810 }
8811 if (startingData != null || removed || firstWindowDrawn) {
8812 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8813 pw.print(" removed="); pw.print(removed);
8814 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8815 }
8816 if (startingWindow != null || startingView != null
8817 || startingDisplayed || startingMoved) {
8818 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8819 pw.print(" startingView="); pw.print(startingView);
8820 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8821 pw.print(" startingMoved"); pw.println(startingMoved);
8822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008823 }
8824
8825 @Override
8826 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008827 if (stringName == null) {
8828 StringBuilder sb = new StringBuilder();
8829 sb.append("AppWindowToken{");
8830 sb.append(Integer.toHexString(System.identityHashCode(this)));
8831 sb.append(" token="); sb.append(token); sb.append('}');
8832 stringName = sb.toString();
8833 }
8834 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008835 }
8836 }
Romain Guy06882f82009-06-10 13:36:04 -07008837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008838 // -------------------------------------------------------------
8839 // DummyAnimation
8840 // -------------------------------------------------------------
8841
8842 // This is an animation that does nothing: it just immediately finishes
8843 // itself every time it is called. It is used as a stub animation in cases
8844 // where we want to synchronize multiple things that may be animating.
8845 static final class DummyAnimation extends Animation {
8846 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8847 return false;
8848 }
8849 }
8850 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852 // -------------------------------------------------------------
8853 // Async Handler
8854 // -------------------------------------------------------------
8855
8856 static final class StartingData {
8857 final String pkg;
8858 final int theme;
8859 final CharSequence nonLocalizedLabel;
8860 final int labelRes;
8861 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07008862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008863 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
8864 int _labelRes, int _icon) {
8865 pkg = _pkg;
8866 theme = _theme;
8867 nonLocalizedLabel = _nonLocalizedLabel;
8868 labelRes = _labelRes;
8869 icon = _icon;
8870 }
8871 }
8872
8873 private final class H extends Handler {
8874 public static final int REPORT_FOCUS_CHANGE = 2;
8875 public static final int REPORT_LOSING_FOCUS = 3;
8876 public static final int ANIMATE = 4;
8877 public static final int ADD_STARTING = 5;
8878 public static final int REMOVE_STARTING = 6;
8879 public static final int FINISHED_STARTING = 7;
8880 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8882 public static final int HOLD_SCREEN_CHANGED = 12;
8883 public static final int APP_TRANSITION_TIMEOUT = 13;
8884 public static final int PERSIST_ANIMATION_SCALE = 14;
8885 public static final int FORCE_GC = 15;
8886 public static final int ENABLE_SCREEN = 16;
8887 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008888 public static final int SEND_NEW_CONFIGURATION = 18;
Romain Guy06882f82009-06-10 13:36:04 -07008889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008892 public H() {
8893 }
Romain Guy06882f82009-06-10 13:36:04 -07008894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008895 @Override
8896 public void handleMessage(Message msg) {
8897 switch (msg.what) {
8898 case REPORT_FOCUS_CHANGE: {
8899 WindowState lastFocus;
8900 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008902 synchronized(mWindowMap) {
8903 lastFocus = mLastFocus;
8904 newFocus = mCurrentFocus;
8905 if (lastFocus == newFocus) {
8906 // Focus is not changing, so nothing to do.
8907 return;
8908 }
8909 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008910 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 // + " to " + newFocus);
8912 if (newFocus != null && lastFocus != null
8913 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008914 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008915 mLosingFocus.add(lastFocus);
8916 lastFocus = null;
8917 }
8918 }
8919
8920 if (lastFocus != newFocus) {
8921 //System.out.println("Changing focus from " + lastFocus
8922 // + " to " + newFocus);
8923 if (newFocus != null) {
8924 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008925 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008926 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8927 } catch (RemoteException e) {
8928 // Ignore if process has died.
8929 }
8930 }
8931
8932 if (lastFocus != null) {
8933 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008934 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008935 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8936 } catch (RemoteException e) {
8937 // Ignore if process has died.
8938 }
8939 }
8940 }
8941 } break;
8942
8943 case REPORT_LOSING_FOCUS: {
8944 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008946 synchronized(mWindowMap) {
8947 losers = mLosingFocus;
8948 mLosingFocus = new ArrayList<WindowState>();
8949 }
8950
8951 final int N = losers.size();
8952 for (int i=0; i<N; i++) {
8953 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008954 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8956 } catch (RemoteException e) {
8957 // Ignore if process has died.
8958 }
8959 }
8960 } break;
8961
8962 case ANIMATE: {
8963 synchronized(mWindowMap) {
8964 mAnimationPending = false;
8965 performLayoutAndPlaceSurfacesLocked();
8966 }
8967 } break;
8968
8969 case ADD_STARTING: {
8970 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8971 final StartingData sd = wtoken.startingData;
8972
8973 if (sd == null) {
8974 // Animation has been canceled... do nothing.
8975 return;
8976 }
Romain Guy06882f82009-06-10 13:36:04 -07008977
Joe Onorato8a9b2202010-02-26 18:56:32 -08008978 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008979 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008981 View view = null;
8982 try {
8983 view = mPolicy.addStartingWindow(
8984 wtoken.token, sd.pkg,
8985 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
8986 sd.icon);
8987 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008988 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008989 }
8990
8991 if (view != null) {
8992 boolean abort = false;
8993
8994 synchronized(mWindowMap) {
8995 if (wtoken.removed || wtoken.startingData == null) {
8996 // If the window was successfully added, then
8997 // we need to remove it.
8998 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008999 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000 "Aborted starting " + wtoken
9001 + ": removed=" + wtoken.removed
9002 + " startingData=" + wtoken.startingData);
9003 wtoken.startingWindow = null;
9004 wtoken.startingData = null;
9005 abort = true;
9006 }
9007 } else {
9008 wtoken.startingView = view;
9009 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009010 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 "Added starting " + wtoken
9012 + ": startingWindow="
9013 + wtoken.startingWindow + " startingView="
9014 + wtoken.startingView);
9015 }
9016
9017 if (abort) {
9018 try {
9019 mPolicy.removeStartingWindow(wtoken.token, view);
9020 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009021 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009022 }
9023 }
9024 }
9025 } break;
9026
9027 case REMOVE_STARTING: {
9028 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9029 IBinder token = null;
9030 View view = null;
9031 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009032 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009033 + wtoken + ": startingWindow="
9034 + wtoken.startingWindow + " startingView="
9035 + wtoken.startingView);
9036 if (wtoken.startingWindow != null) {
9037 view = wtoken.startingView;
9038 token = wtoken.token;
9039 wtoken.startingData = null;
9040 wtoken.startingView = null;
9041 wtoken.startingWindow = null;
9042 }
9043 }
9044 if (view != null) {
9045 try {
9046 mPolicy.removeStartingWindow(token, view);
9047 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009048 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 }
9050 }
9051 } break;
9052
9053 case FINISHED_STARTING: {
9054 IBinder token = null;
9055 View view = null;
9056 while (true) {
9057 synchronized (mWindowMap) {
9058 final int N = mFinishedStarting.size();
9059 if (N <= 0) {
9060 break;
9061 }
9062 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9063
Joe Onorato8a9b2202010-02-26 18:56:32 -08009064 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009065 "Finished starting " + wtoken
9066 + ": startingWindow=" + wtoken.startingWindow
9067 + " startingView=" + wtoken.startingView);
9068
9069 if (wtoken.startingWindow == null) {
9070 continue;
9071 }
9072
9073 view = wtoken.startingView;
9074 token = wtoken.token;
9075 wtoken.startingData = null;
9076 wtoken.startingView = null;
9077 wtoken.startingWindow = null;
9078 }
9079
9080 try {
9081 mPolicy.removeStartingWindow(token, view);
9082 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009083 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 }
9085 }
9086 } break;
9087
9088 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9089 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9090
9091 boolean nowVisible = msg.arg1 != 0;
9092 boolean nowGone = msg.arg2 != 0;
9093
9094 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009095 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009096 TAG, "Reporting visible in " + wtoken
9097 + " visible=" + nowVisible
9098 + " gone=" + nowGone);
9099 if (nowVisible) {
9100 wtoken.appToken.windowsVisible();
9101 } else {
9102 wtoken.appToken.windowsGone();
9103 }
9104 } catch (RemoteException ex) {
9105 }
9106 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 case WINDOW_FREEZE_TIMEOUT: {
9109 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009110 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009111 int i = mWindows.size();
9112 while (i > 0) {
9113 i--;
9114 WindowState w = (WindowState)mWindows.get(i);
9115 if (w.mOrientationChanging) {
9116 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009117 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009118 }
9119 }
9120 performLayoutAndPlaceSurfacesLocked();
9121 }
9122 break;
9123 }
Romain Guy06882f82009-06-10 13:36:04 -07009124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009125 case HOLD_SCREEN_CHANGED: {
9126 Session oldHold;
9127 Session newHold;
9128 synchronized (mWindowMap) {
9129 oldHold = mLastReportedHold;
9130 newHold = (Session)msg.obj;
9131 mLastReportedHold = newHold;
9132 }
Romain Guy06882f82009-06-10 13:36:04 -07009133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009134 if (oldHold != newHold) {
9135 try {
9136 if (oldHold != null) {
9137 mBatteryStats.noteStopWakelock(oldHold.mUid,
9138 "window",
9139 BatteryStats.WAKE_TYPE_WINDOW);
9140 }
9141 if (newHold != null) {
9142 mBatteryStats.noteStartWakelock(newHold.mUid,
9143 "window",
9144 BatteryStats.WAKE_TYPE_WINDOW);
9145 }
9146 } catch (RemoteException e) {
9147 }
9148 }
9149 break;
9150 }
Romain Guy06882f82009-06-10 13:36:04 -07009151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 case APP_TRANSITION_TIMEOUT: {
9153 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009154 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009155 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009156 "*** APP TRANSITION TIMEOUT");
9157 mAppTransitionReady = true;
9158 mAppTransitionTimeout = true;
9159 performLayoutAndPlaceSurfacesLocked();
9160 }
9161 }
9162 break;
9163 }
Romain Guy06882f82009-06-10 13:36:04 -07009164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 case PERSIST_ANIMATION_SCALE: {
9166 Settings.System.putFloat(mContext.getContentResolver(),
9167 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9168 Settings.System.putFloat(mContext.getContentResolver(),
9169 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9170 break;
9171 }
Romain Guy06882f82009-06-10 13:36:04 -07009172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009173 case FORCE_GC: {
9174 synchronized(mWindowMap) {
9175 if (mAnimationPending) {
9176 // If we are animating, don't do the gc now but
9177 // delay a bit so we don't interrupt the animation.
9178 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9179 2000);
9180 return;
9181 }
9182 // If we are currently rotating the display, it will
9183 // schedule a new message when done.
9184 if (mDisplayFrozen) {
9185 return;
9186 }
9187 mFreezeGcPending = 0;
9188 }
9189 Runtime.getRuntime().gc();
9190 break;
9191 }
Romain Guy06882f82009-06-10 13:36:04 -07009192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009193 case ENABLE_SCREEN: {
9194 performEnableScreen();
9195 break;
9196 }
Romain Guy06882f82009-06-10 13:36:04 -07009197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009198 case APP_FREEZE_TIMEOUT: {
9199 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009200 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009201 int i = mAppTokens.size();
9202 while (i > 0) {
9203 i--;
9204 AppWindowToken tok = mAppTokens.get(i);
9205 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009206 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009207 unsetAppFreezingScreenLocked(tok, true, true);
9208 }
9209 }
9210 }
9211 break;
9212 }
Romain Guy06882f82009-06-10 13:36:04 -07009213
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009214 case SEND_NEW_CONFIGURATION: {
9215 removeMessages(SEND_NEW_CONFIGURATION);
9216 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009217 break;
9218 }
Romain Guy06882f82009-06-10 13:36:04 -07009219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009220 }
9221 }
9222 }
9223
9224 // -------------------------------------------------------------
9225 // IWindowManager API
9226 // -------------------------------------------------------------
9227
9228 public IWindowSession openSession(IInputMethodClient client,
9229 IInputContext inputContext) {
9230 if (client == null) throw new IllegalArgumentException("null client");
9231 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
9232 return new Session(client, inputContext);
9233 }
9234
9235 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9236 synchronized (mWindowMap) {
9237 // The focus for the client is the window immediately below
9238 // where we would place the input method window.
9239 int idx = findDesiredInputMethodWindowIndexLocked(false);
9240 WindowState imFocus;
9241 if (idx > 0) {
9242 imFocus = (WindowState)mWindows.get(idx-1);
9243 if (imFocus != null) {
9244 if (imFocus.mSession.mClient != null &&
9245 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9246 return true;
9247 }
9248 }
9249 }
9250 }
9251 return false;
9252 }
Romain Guy06882f82009-06-10 13:36:04 -07009253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 // -------------------------------------------------------------
9255 // Internals
9256 // -------------------------------------------------------------
9257
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009258 final WindowState windowForClientLocked(Session session, IWindow client,
9259 boolean throwOnError) {
9260 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261 }
Romain Guy06882f82009-06-10 13:36:04 -07009262
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009263 final WindowState windowForClientLocked(Session session, IBinder client,
9264 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009266 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009267 TAG, "Looking up client " + client + ": " + win);
9268 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009269 RuntimeException ex = new IllegalArgumentException(
9270 "Requested window " + client + " does not exist");
9271 if (throwOnError) {
9272 throw ex;
9273 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009274 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009275 return null;
9276 }
9277 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009278 RuntimeException ex = new IllegalArgumentException(
9279 "Requested window " + client + " is in session " +
9280 win.mSession + ", not " + session);
9281 if (throwOnError) {
9282 throw ex;
9283 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009284 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009285 return null;
9286 }
9287
9288 return win;
9289 }
9290
Dianne Hackborna8f60182009-09-01 19:01:50 -07009291 final void rebuildAppWindowListLocked() {
9292 int NW = mWindows.size();
9293 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009294 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009295 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009296
Dianne Hackborna8f60182009-09-01 19:01:50 -07009297 // First remove all existing app windows.
9298 i=0;
9299 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009300 WindowState w = (WindowState)mWindows.get(i);
9301 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009302 WindowState win = (WindowState)mWindows.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009303 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009304 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009305 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009306 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009307 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009308 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9309 && lastWallpaper == i-1) {
9310 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009311 }
9312 i++;
9313 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009314
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009315 // The wallpaper window(s) typically live at the bottom of the stack,
9316 // so skip them before adding app tokens.
9317 lastWallpaper++;
9318 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009319
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009320 // First add all of the exiting app tokens... these are no longer
9321 // in the main app list, but still have windows shown. We put them
9322 // in the back because now that the animation is over we no longer
9323 // will care about them.
9324 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009325 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009326 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9327 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009328
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009329 // And add in the still active app tokens in Z order.
9330 NT = mAppTokens.size();
9331 for (int j=0; j<NT; j++) {
9332 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009333 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009334
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009335 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009336 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009337 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009338 + " windows but added " + i);
9339 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009340 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009342 private final void assignLayersLocked() {
9343 int N = mWindows.size();
9344 int curBaseLayer = 0;
9345 int curLayer = 0;
9346 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009348 for (i=0; i<N; i++) {
9349 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009350 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9351 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009352 curLayer += WINDOW_LAYER_MULTIPLIER;
9353 w.mLayer = curLayer;
9354 } else {
9355 curBaseLayer = curLayer = w.mBaseLayer;
9356 w.mLayer = curLayer;
9357 }
9358 if (w.mTargetAppToken != null) {
9359 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9360 } else if (w.mAppToken != null) {
9361 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9362 } else {
9363 w.mAnimLayer = w.mLayer;
9364 }
9365 if (w.mIsImWindow) {
9366 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009367 } else if (w.mIsWallpaper) {
9368 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009370 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 + w.mAnimLayer);
9372 //System.out.println(
9373 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9374 }
9375 }
9376
9377 private boolean mInLayout = false;
9378 private final void performLayoutAndPlaceSurfacesLocked() {
9379 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009380 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 throw new RuntimeException("Recursive call!");
9382 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009383 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384 return;
9385 }
9386
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009387 if (mWaitingForConfig) {
9388 // Our configuration has changed (most likely rotation), but we
9389 // don't yet have the complete configuration to report to
9390 // applications. Don't do any window layout until we have it.
9391 return;
9392 }
9393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 boolean recoveringMemory = false;
9395 if (mForceRemoves != null) {
9396 recoveringMemory = true;
9397 // Wait a little it for things to settle down, and off we go.
9398 for (int i=0; i<mForceRemoves.size(); i++) {
9399 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009400 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 removeWindowInnerLocked(ws.mSession, ws);
9402 }
9403 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009404 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009405 Object tmp = new Object();
9406 synchronized (tmp) {
9407 try {
9408 tmp.wait(250);
9409 } catch (InterruptedException e) {
9410 }
9411 }
9412 }
Romain Guy06882f82009-06-10 13:36:04 -07009413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009414 mInLayout = true;
9415 try {
9416 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009418 int i = mPendingRemove.size()-1;
9419 if (i >= 0) {
9420 while (i >= 0) {
9421 WindowState w = mPendingRemove.get(i);
9422 removeWindowInnerLocked(w.mSession, w);
9423 i--;
9424 }
9425 mPendingRemove.clear();
9426
9427 mInLayout = false;
9428 assignLayersLocked();
9429 mLayoutNeeded = true;
9430 performLayoutAndPlaceSurfacesLocked();
9431
9432 } else {
9433 mInLayout = false;
9434 if (mLayoutNeeded) {
9435 requestAnimationLocked(0);
9436 }
9437 }
9438 } catch (RuntimeException e) {
9439 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009440 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009441 }
9442 }
9443
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009444 private final int performLayoutLockedInner() {
9445 if (!mLayoutNeeded) {
9446 return 0;
9447 }
9448
9449 mLayoutNeeded = false;
9450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 final int dw = mDisplay.getWidth();
9452 final int dh = mDisplay.getHeight();
9453
9454 final int N = mWindows.size();
9455 int i;
9456
Joe Onorato8a9b2202010-02-26 18:56:32 -08009457 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009458 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9459
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009460 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009461
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009462 int seq = mLayoutSeq+1;
9463 if (seq < 0) seq = 0;
9464 mLayoutSeq = seq;
9465
9466 // First perform layout of any root windows (not attached
9467 // to another window).
9468 int topAttached = -1;
9469 for (i = N-1; i >= 0; i--) {
9470 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009472 // Don't do layout of a window if it is not visible, or
9473 // soon won't be visible, to avoid wasting time and funky
9474 // changes while a window is animating away.
9475 final AppWindowToken atoken = win.mAppToken;
9476 final boolean gone = win.mViewVisibility == View.GONE
9477 || !win.mRelayoutCalled
9478 || win.mRootToken.hidden
9479 || (atoken != null && atoken.hiddenRequested)
9480 || win.mAttachedHidden
9481 || win.mExiting || win.mDestroying;
9482
9483 if (!win.mLayoutAttached) {
9484 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
9485 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9486 + " mLayoutAttached=" + win.mLayoutAttached);
9487 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
9488 + win.mViewVisibility + " mRelayoutCalled="
9489 + win.mRelayoutCalled + " hidden="
9490 + win.mRootToken.hidden + " hiddenRequested="
9491 + (atoken != null && atoken.hiddenRequested)
9492 + " mAttachedHidden=" + win.mAttachedHidden);
9493 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009494
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009495 // If this view is GONE, then skip it -- keep the current
9496 // frame, and let the caller know so they can ignore it
9497 // if they want. (We do the normal layout for INVISIBLE
9498 // windows, since that means "perform layout as normal,
9499 // just don't display").
9500 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009501 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009502 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9503 win.mLayoutSeq = seq;
9504 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9505 + win.mFrame + " mContainingFrame="
9506 + win.mContainingFrame + " mDisplayFrame="
9507 + win.mDisplayFrame);
9508 } else {
9509 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009510 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009513
9514 // Now perform layout of attached windows, which usually
9515 // depend on the position of the window they are attached to.
9516 // XXX does not deal with windows that are attached to windows
9517 // that are themselves attached.
9518 for (i = topAttached; i >= 0; i--) {
9519 WindowState win = (WindowState) mWindows.get(i);
9520
9521 // If this view is GONE, then skip it -- keep the current
9522 // frame, and let the caller know so they can ignore it
9523 // if they want. (We do the normal layout for INVISIBLE
9524 // windows, since that means "perform layout as normal,
9525 // just don't display").
9526 if (win.mLayoutAttached) {
9527 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9528 + " mHaveFrame=" + win.mHaveFrame
9529 + " mViewVisibility=" + win.mViewVisibility
9530 + " mRelayoutCalled=" + win.mRelayoutCalled);
9531 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9532 || !win.mHaveFrame) {
9533 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9534 win.mLayoutSeq = seq;
9535 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9536 + win.mFrame + " mContainingFrame="
9537 + win.mContainingFrame + " mDisplayFrame="
9538 + win.mDisplayFrame);
9539 }
9540 }
9541 }
9542
9543 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009544 }
Romain Guy06882f82009-06-10 13:36:04 -07009545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009546 private final void performLayoutAndPlaceSurfacesLockedInner(
9547 boolean recoveringMemory) {
9548 final long currentTime = SystemClock.uptimeMillis();
9549 final int dw = mDisplay.getWidth();
9550 final int dh = mDisplay.getHeight();
9551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552 int i;
9553
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009554 if (mFocusMayChange) {
9555 mFocusMayChange = false;
9556 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9557 }
9558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 if (mFxSession == null) {
9560 mFxSession = new SurfaceSession();
9561 }
Romain Guy06882f82009-06-10 13:36:04 -07009562
Joe Onorato8a9b2202010-02-26 18:56:32 -08009563 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564
9565 // Initialize state of exiting tokens.
9566 for (i=mExitingTokens.size()-1; i>=0; i--) {
9567 mExitingTokens.get(i).hasVisible = false;
9568 }
9569
9570 // Initialize state of exiting applications.
9571 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9572 mExitingAppTokens.get(i).hasVisible = false;
9573 }
9574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 boolean orientationChangeComplete = true;
9576 Session holdScreen = null;
9577 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009578 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009579 boolean focusDisplayed = false;
9580 boolean animating = false;
9581
9582 Surface.openTransaction();
9583 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009584 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009585 int repeats = 0;
9586 int changes = 0;
9587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009588 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009589 repeats++;
9590 if (repeats > 6) {
9591 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9592 mLayoutNeeded = false;
9593 break;
9594 }
9595
9596 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9597 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9598 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9599 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9600 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9601 assignLayersLocked();
9602 mLayoutNeeded = true;
9603 }
9604 }
9605 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9606 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9607 if (updateOrientationFromAppTokensLocked()) {
9608 mLayoutNeeded = true;
9609 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9610 }
9611 }
9612 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9613 mLayoutNeeded = true;
9614 }
9615 }
9616
9617 // FIRST LOOP: Perform a layout, if needed.
9618 if (repeats < 4) {
9619 changes = performLayoutLockedInner();
9620 if (changes != 0) {
9621 continue;
9622 }
9623 } else {
9624 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9625 changes = 0;
9626 }
9627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009628 final int transactionSequence = ++mTransactionSequence;
9629
9630 // Update animations of all applications, including those
9631 // associated with exiting/removed apps
9632 boolean tokensAnimating = false;
9633 final int NAT = mAppTokens.size();
9634 for (i=0; i<NAT; i++) {
9635 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9636 tokensAnimating = true;
9637 }
9638 }
9639 final int NEAT = mExitingAppTokens.size();
9640 for (i=0; i<NEAT; i++) {
9641 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9642 tokensAnimating = true;
9643 }
9644 }
9645
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009646 // SECOND LOOP: Execute animations and update visibility of windows.
9647
Joe Onorato8a9b2202010-02-26 18:56:32 -08009648 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009649 + transactionSequence + " tokensAnimating="
9650 + tokensAnimating);
9651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009653
9654 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009655 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009656 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657
9658 mPolicy.beginAnimationLw(dw, dh);
9659
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009660 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009662 for (i=N-1; i>=0; i--) {
9663 WindowState w = (WindowState)mWindows.get(i);
9664
9665 final WindowManager.LayoutParams attrs = w.mAttrs;
9666
9667 if (w.mSurface != null) {
9668 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009669 if (w.commitFinishDrawingLocked(currentTime)) {
9670 if ((w.mAttrs.flags
9671 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009672 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009673 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009674 wallpaperMayChange = true;
9675 }
9676 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009677
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009678 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009679 if (w.stepAnimationLocked(currentTime, dw, dh)) {
9680 animating = true;
9681 //w.dump(" ");
9682 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009683 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9684 wallpaperMayChange = true;
9685 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009686
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009687 if (mPolicy.doesForceHide(w, attrs)) {
9688 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009689 if (DEBUG_VISIBILITY) Slog.v(TAG,
9690 "Animation done that could impact force hide: "
9691 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009692 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009693 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009694 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9695 forceHiding = true;
9696 }
9697 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9698 boolean changed;
9699 if (forceHiding) {
9700 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009701 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9702 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009703 } else {
9704 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009705 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9706 "Now policy shown: " + w);
9707 if (changed) {
9708 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009709 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009710 // Assume we will need to animate. If
9711 // we don't (because the wallpaper will
9712 // stay with the lock screen), then we will
9713 // clean up later.
9714 Animation a = mPolicy.createForceHideEnterAnimation();
9715 if (a != null) {
9716 w.setAnimation(a);
9717 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009718 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009719 if (mCurrentFocus == null ||
9720 mCurrentFocus.mLayer < w.mLayer) {
9721 // We are showing on to of the current
9722 // focus, so re-evaluate focus to make
9723 // sure it is correct.
9724 mFocusMayChange = true;
9725 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009726 }
9727 }
9728 if (changed && (attrs.flags
9729 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9730 wallpaperMayChange = true;
9731 }
9732 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009734 mPolicy.animatingWindowLw(w, attrs);
9735 }
9736
9737 final AppWindowToken atoken = w.mAppToken;
9738 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9739 if (atoken.lastTransactionSequence != transactionSequence) {
9740 atoken.lastTransactionSequence = transactionSequence;
9741 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9742 atoken.startingDisplayed = false;
9743 }
9744 if ((w.isOnScreen() || w.mAttrs.type
9745 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9746 && !w.mExiting && !w.mDestroying) {
9747 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009748 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009749 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009750 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009751 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009752 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009753 + " pv=" + w.mPolicyVisibility
9754 + " dp=" + w.mDrawPending
9755 + " cdp=" + w.mCommitDrawPending
9756 + " ah=" + w.mAttachedHidden
9757 + " th=" + atoken.hiddenRequested
9758 + " a=" + w.mAnimating);
9759 }
9760 }
9761 if (w != atoken.startingWindow) {
9762 if (!atoken.freezingScreen || !w.mAppFreezing) {
9763 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009764 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009766 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 "tokenMayBeDrawn: " + atoken
9768 + " freezingScreen=" + atoken.freezingScreen
9769 + " mAppFreezing=" + w.mAppFreezing);
9770 tokenMayBeDrawn = true;
9771 }
9772 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009773 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009774 atoken.startingDisplayed = true;
9775 }
9776 }
9777 } else if (w.mReadyToShow) {
9778 w.performShowLocked();
9779 }
9780 }
9781
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009782 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009783
9784 if (tokenMayBeDrawn) {
9785 // See if any windows have been drawn, so they (and others
9786 // associated with them) can now be shown.
9787 final int NT = mTokenList.size();
9788 for (i=0; i<NT; i++) {
9789 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9790 if (wtoken == null) {
9791 continue;
9792 }
9793 if (wtoken.freezingScreen) {
9794 int numInteresting = wtoken.numInterestingWindows;
9795 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009796 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 "allDrawn: " + wtoken
9798 + " interesting=" + numInteresting
9799 + " drawn=" + wtoken.numDrawnWindows);
9800 wtoken.showAllWindowsLocked();
9801 unsetAppFreezingScreenLocked(wtoken, false, true);
9802 orientationChangeComplete = true;
9803 }
9804 } else if (!wtoken.allDrawn) {
9805 int numInteresting = wtoken.numInterestingWindows;
9806 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009807 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009808 "allDrawn: " + wtoken
9809 + " interesting=" + numInteresting
9810 + " drawn=" + wtoken.numDrawnWindows);
9811 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009812 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813
9814 // We can now show all of the drawn windows!
9815 if (!mOpeningApps.contains(wtoken)) {
9816 wtoken.showAllWindowsLocked();
9817 }
9818 }
9819 }
9820 }
9821 }
9822
9823 // If we are ready to perform an app transition, check through
9824 // all of the app tokens to be shown and see if they are ready
9825 // to go.
9826 if (mAppTransitionReady) {
9827 int NN = mOpeningApps.size();
9828 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009829 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009830 "Checking " + NN + " opening apps (frozen="
9831 + mDisplayFrozen + " timeout="
9832 + mAppTransitionTimeout + ")...");
9833 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9834 // If the display isn't frozen, wait to do anything until
9835 // all of the apps are ready. Otherwise just go because
9836 // we'll unfreeze the display when everyone is ready.
9837 for (i=0; i<NN && goodToGo; i++) {
9838 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009839 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 "Check opening app" + wtoken + ": allDrawn="
9841 + wtoken.allDrawn + " startingDisplayed="
9842 + wtoken.startingDisplayed);
9843 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9844 && !wtoken.startingMoved) {
9845 goodToGo = false;
9846 }
9847 }
9848 }
9849 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009850 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 int transit = mNextAppTransition;
9852 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009853 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009855 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009857 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 mAppTransitionTimeout = false;
9859 mStartingIconInTransition = false;
9860 mSkipAppTransitionAnimation = false;
9861
9862 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9863
Dianne Hackborna8f60182009-09-01 19:01:50 -07009864 // If there are applications waiting to come to the
9865 // top of the stack, now is the time to move their windows.
9866 // (Note that we don't do apps going to the bottom
9867 // here -- we want to keep their windows in the old
9868 // Z-order until the animation completes.)
9869 if (mToTopApps.size() > 0) {
9870 NN = mAppTokens.size();
9871 for (i=0; i<NN; i++) {
9872 AppWindowToken wtoken = mAppTokens.get(i);
9873 if (wtoken.sendingToTop) {
9874 wtoken.sendingToTop = false;
9875 moveAppWindowsLocked(wtoken, NN, false);
9876 }
9877 }
9878 mToTopApps.clear();
9879 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009880
Dianne Hackborn25994b42009-09-04 14:21:19 -07009881 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009882
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009883 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009884 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009885
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009886 // The top-most window will supply the layout params,
9887 // and we will determine it below.
9888 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009889 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009890 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009891
Joe Onorato8a9b2202010-02-26 18:56:32 -08009892 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009893 "New wallpaper target=" + mWallpaperTarget
9894 + ", lower target=" + mLowerWallpaperTarget
9895 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009896 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009897 // Do a first pass through the tokens for two
9898 // things:
9899 // (1) Determine if both the closing and opening
9900 // app token sets are wallpaper targets, in which
9901 // case special animations are needed
9902 // (since the wallpaper needs to stay static
9903 // behind them).
9904 // (2) Find the layout params of the top-most
9905 // application window in the tokens, which is
9906 // what will control the animation theme.
9907 final int NC = mClosingApps.size();
9908 NN = NC + mOpeningApps.size();
9909 for (i=0; i<NN; i++) {
9910 AppWindowToken wtoken;
9911 int mode;
9912 if (i < NC) {
9913 wtoken = mClosingApps.get(i);
9914 mode = 1;
9915 } else {
9916 wtoken = mOpeningApps.get(i-NC);
9917 mode = 2;
9918 }
9919 if (mLowerWallpaperTarget != null) {
9920 if (mLowerWallpaperTarget.mAppToken == wtoken
9921 || mUpperWallpaperTarget.mAppToken == wtoken) {
9922 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009923 }
9924 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009925 if (wtoken.appFullscreen) {
9926 WindowState ws = wtoken.findMainWindow();
9927 if (ws != null) {
9928 // If this is a compatibility mode
9929 // window, we will always use its anim.
9930 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9931 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009932 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009933 bestAnimLayer = Integer.MAX_VALUE;
9934 } else if (ws.mLayer > bestAnimLayer) {
9935 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009936 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009937 bestAnimLayer = ws.mLayer;
9938 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009939 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009940 }
9941 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009942
Dianne Hackborn25994b42009-09-04 14:21:19 -07009943 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009944 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009945 "Wallpaper animation!");
9946 switch (transit) {
9947 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9948 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9949 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9950 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9951 break;
9952 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9953 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9954 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9955 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9956 break;
9957 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009958 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009959 "New transit: " + transit);
9960 } else if (oldWallpaper != null) {
9961 // We are transitioning from an activity with
9962 // a wallpaper to one without.
9963 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009964 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009965 "New transit away from wallpaper: " + transit);
9966 } else if (mWallpaperTarget != null) {
9967 // We are transitioning from an activity without
9968 // a wallpaper to now showing the wallpaper
9969 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009970 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009971 "New transit into wallpaper: " + transit);
9972 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009973
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009974 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9975 mLastEnterAnimToken = animToken;
9976 mLastEnterAnimParams = animLp;
9977 } else if (mLastEnterAnimParams != null) {
9978 animLp = mLastEnterAnimParams;
9979 mLastEnterAnimToken = null;
9980 mLastEnterAnimParams = null;
9981 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009982
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009983 // If all closing windows are obscured, then there is
9984 // no need to do an animation. This is the case, for
9985 // example, when this transition is being done behind
9986 // the lock screen.
9987 if (!mPolicy.allowAppAnimationsLw()) {
9988 animLp = null;
9989 }
9990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009991 NN = mOpeningApps.size();
9992 for (i=0; i<NN; i++) {
9993 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009994 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 "Now opening app" + wtoken);
9996 wtoken.reportedVisible = false;
9997 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009998 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009999 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010001 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010002 wtoken.showAllWindowsLocked();
10003 }
10004 NN = mClosingApps.size();
10005 for (i=0; i<NN; i++) {
10006 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010007 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010008 "Now closing app" + wtoken);
10009 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010010 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010011 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010013 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 // Force the allDrawn flag, because we want to start
10015 // this guy's animations regardless of whether it's
10016 // gotten drawn.
10017 wtoken.allDrawn = true;
10018 }
10019
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010020 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 mOpeningApps.clear();
10023 mClosingApps.clear();
10024
10025 // This has changed the visibility of windows, so perform
10026 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010027 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010029 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10030 assignLayersLocked();
10031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010032 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010033 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010034 }
10035 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010036
Dianne Hackborn16064f92010-03-25 00:47:24 -070010037 int adjResult = 0;
10038
Dianne Hackborna8f60182009-09-01 19:01:50 -070010039 if (!animating && mAppTransitionRunning) {
10040 // We have finished the animation of an app transition. To do
10041 // this, we have delayed a lot of operations like showing and
10042 // hiding apps, moving apps in Z-order, etc. The app token list
10043 // reflects the correct Z-order, but the window list may now
10044 // be out of sync with it. So here we will just rebuild the
10045 // entire app window list. Fun!
10046 mAppTransitionRunning = false;
10047 // Clear information about apps that were moving.
10048 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010049
Dianne Hackborna8f60182009-09-01 19:01:50 -070010050 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010051 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010052 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010053 moveInputMethodWindowsIfNeededLocked(false);
10054 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010055 // Since the window list has been rebuilt, focus might
10056 // have to be recomputed since the actual order of windows
10057 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010058 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010059 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010060
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010061 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010062 // At this point, there was a window with a wallpaper that
10063 // was force hiding other windows behind it, but now it
10064 // is going away. This may be simple -- just animate
10065 // away the wallpaper and its window -- or it may be
10066 // hard -- the wallpaper now needs to be shown behind
10067 // something that was hidden.
10068 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010069 if (mLowerWallpaperTarget != null
10070 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010071 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010072 "wallpaperForceHiding changed with lower="
10073 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010074 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010075 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10076 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10077 if (mLowerWallpaperTarget.mAppToken.hidden) {
10078 // The lower target has become hidden before we
10079 // actually started the animation... let's completely
10080 // re-evaluate everything.
10081 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010082 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010083 }
10084 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010085 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010086 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010087 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010088 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010089 + " NEW: " + mWallpaperTarget
10090 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010091 if (mLowerWallpaperTarget == null) {
10092 // Whoops, we don't need a special wallpaper animation.
10093 // Clear them out.
10094 forceHiding = false;
10095 for (i=N-1; i>=0; i--) {
10096 WindowState w = (WindowState)mWindows.get(i);
10097 if (w.mSurface != null) {
10098 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010099 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010100 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010101 forceHiding = true;
10102 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10103 if (!w.mAnimating) {
10104 // We set the animation above so it
10105 // is not yet running.
10106 w.clearAnimation();
10107 }
10108 }
10109 }
10110 }
10111 }
10112 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010113
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010114 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010115 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010116 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010117 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010118 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010119
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010120 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010121 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010122 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010123 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010124 assignLayersLocked();
10125 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010126 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010127 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010128 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010129 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010130
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010131 if (mFocusMayChange) {
10132 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010133 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010134 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010135 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010136 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010137 }
10138
10139 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010140 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010141 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010142
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010143 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10144 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010145
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010146 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010147
10148 // THIRD LOOP: Update the surfaces of all windows.
10149
10150 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10151
10152 boolean obscured = false;
10153 boolean blurring = false;
10154 boolean dimming = false;
10155 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010156 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010157 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010159 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010161 for (i=N-1; i>=0; i--) {
10162 WindowState w = (WindowState)mWindows.get(i);
10163
10164 boolean displayed = false;
10165 final WindowManager.LayoutParams attrs = w.mAttrs;
10166 final int attrFlags = attrs.flags;
10167
10168 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010169 // XXX NOTE: The logic here could be improved. We have
10170 // the decision about whether to resize a window separated
10171 // from whether to hide the surface. This can cause us to
10172 // resize a surface even if we are going to hide it. You
10173 // can see this by (1) holding device in landscape mode on
10174 // home screen; (2) tapping browser icon (device will rotate
10175 // to landscape; (3) tap home. The wallpaper will be resized
10176 // in step 2 but then immediately hidden, causing us to
10177 // have to resize and then redraw it again in step 3. It
10178 // would be nice to figure out how to avoid this, but it is
10179 // difficult because we do need to resize surfaces in some
10180 // cases while they are hidden such as when first showing a
10181 // window.
10182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010184 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 TAG, "Placing surface #" + i + " " + w.mSurface
10186 + ": new=" + w.mShownFrame + ", old="
10187 + w.mLastShownFrame);
10188
10189 boolean resize;
10190 int width, height;
10191 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10192 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10193 w.mLastRequestedHeight != w.mRequestedHeight;
10194 // for a scaled surface, we just want to use
10195 // the requested size.
10196 width = w.mRequestedWidth;
10197 height = w.mRequestedHeight;
10198 w.mLastRequestedWidth = width;
10199 w.mLastRequestedHeight = height;
10200 w.mLastShownFrame.set(w.mShownFrame);
10201 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010202 if (SHOW_TRANSACTIONS) logSurface(w,
10203 "POS " + w.mShownFrame.left
10204 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010205 w.mSurfaceX = w.mShownFrame.left;
10206 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010207 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10208 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010209 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010210 if (!recoveringMemory) {
10211 reclaimSomeSurfaceMemoryLocked(w, "position");
10212 }
10213 }
10214 } else {
10215 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10216 width = w.mShownFrame.width();
10217 height = w.mShownFrame.height();
10218 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 }
10220
10221 if (resize) {
10222 if (width < 1) width = 1;
10223 if (height < 1) height = 1;
10224 if (w.mSurface != null) {
10225 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010226 if (SHOW_TRANSACTIONS) logSurface(w,
10227 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010228 + w.mShownFrame.top + " SIZE "
10229 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010230 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010231 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010232 w.mSurfaceW = width;
10233 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010235 w.mSurfaceX = w.mShownFrame.left;
10236 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010237 w.mSurface.setPosition(w.mShownFrame.left,
10238 w.mShownFrame.top);
10239 } catch (RuntimeException e) {
10240 // If something goes wrong with the surface (such
10241 // as running out of memory), don't take down the
10242 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010243 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 + "size=(" + width + "x" + height
10245 + "), pos=(" + w.mShownFrame.left
10246 + "," + w.mShownFrame.top + ")", e);
10247 if (!recoveringMemory) {
10248 reclaimSomeSurfaceMemoryLocked(w, "size");
10249 }
10250 }
10251 }
10252 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010253 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 w.mContentInsetsChanged =
10255 !w.mLastContentInsets.equals(w.mContentInsets);
10256 w.mVisibleInsetsChanged =
10257 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010258 boolean configChanged =
10259 w.mConfiguration != mCurConfiguration
10260 && (w.mConfiguration == null
10261 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010262 if (DEBUG_CONFIGURATION && configChanged) {
10263 Slog.v(TAG, "Win " + w + " config changed: "
10264 + mCurConfiguration);
10265 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010266 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010267 + ": configChanged=" + configChanged
10268 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010269 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010271 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010272 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010273 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 w.mLastFrame.set(w.mFrame);
10275 w.mLastContentInsets.set(w.mContentInsets);
10276 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010277 // If the screen is currently frozen, then keep
10278 // it frozen until this window draws at its new
10279 // orientation.
10280 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010281 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010282 "Resizing while display frozen: " + w);
10283 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010284 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010285 mWindowsFreezingScreen = true;
10286 // XXX should probably keep timeout from
10287 // when we first froze the display.
10288 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10289 mH.sendMessageDelayed(mH.obtainMessage(
10290 H.WINDOW_FREEZE_TIMEOUT), 2000);
10291 }
10292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 // If the orientation is changing, then we need to
10294 // hold off on unfreezing the display until this
10295 // window has been redrawn; to do that, we need
10296 // to go through the process of getting informed
10297 // by the application when it has finished drawing.
10298 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010299 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 "Orientation start waiting for draw in "
10301 + w + ", surface " + w.mSurface);
10302 w.mDrawPending = true;
10303 w.mCommitDrawPending = false;
10304 w.mReadyToShow = false;
10305 if (w.mAppToken != null) {
10306 w.mAppToken.allDrawn = false;
10307 }
10308 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010309 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010310 "Resizing window " + w + " to " + w.mFrame);
10311 mResizingWindows.add(w);
10312 } else if (w.mOrientationChanging) {
10313 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010314 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010315 "Orientation not waiting for draw in "
10316 + w + ", surface " + w.mSurface);
10317 w.mOrientationChanging = false;
10318 }
10319 }
10320 }
10321
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010322 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 if (!w.mLastHidden) {
10324 //dump();
Dianne Hackborn5943c202010-04-12 21:36:49 -070010325 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Window hiding: waitingToShow="
10326 + w.mRootToken.waitingToShow + " polvis="
10327 + w.mPolicyVisibility + " atthid="
10328 + w.mAttachedHidden + " tokhid="
10329 + w.mRootToken.hidden + " vis="
10330 + w.mViewVisibility);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010332 if (SHOW_TRANSACTIONS) logSurface(w,
10333 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010335 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 try {
10337 w.mSurface.hide();
10338 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010339 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010340 }
10341 }
10342 mKeyWaiter.releasePendingPointerLocked(w.mSession);
10343 }
10344 // If we are waiting for this window to handle an
10345 // orientation change, well, it is hidden, so
10346 // doesn't really matter. Note that this does
10347 // introduce a potential glitch if the window
10348 // becomes unhidden before it has drawn for the
10349 // new orientation.
10350 if (w.mOrientationChanging) {
10351 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010352 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 "Orientation change skips hidden " + w);
10354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010355 } else if (w.mLastLayer != w.mAnimLayer
10356 || w.mLastAlpha != w.mShownAlpha
10357 || w.mLastDsDx != w.mDsDx
10358 || w.mLastDtDx != w.mDtDx
10359 || w.mLastDsDy != w.mDsDy
10360 || w.mLastDtDy != w.mDtDy
10361 || w.mLastHScale != w.mHScale
10362 || w.mLastVScale != w.mVScale
10363 || w.mLastHidden) {
10364 displayed = true;
10365 w.mLastAlpha = w.mShownAlpha;
10366 w.mLastLayer = w.mAnimLayer;
10367 w.mLastDsDx = w.mDsDx;
10368 w.mLastDtDx = w.mDtDx;
10369 w.mLastDsDy = w.mDsDy;
10370 w.mLastDtDy = w.mDtDy;
10371 w.mLastHScale = w.mHScale;
10372 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010373 if (SHOW_TRANSACTIONS) logSurface(w,
10374 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010375 + " matrix=[" + (w.mDsDx*w.mHScale)
10376 + "," + (w.mDtDx*w.mVScale)
10377 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010378 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 if (w.mSurface != null) {
10380 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010381 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010382 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010383 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 w.mSurface.setLayer(w.mAnimLayer);
10385 w.mSurface.setMatrix(
10386 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10387 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10388 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010389 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 if (!recoveringMemory) {
10391 reclaimSomeSurfaceMemoryLocked(w, "update");
10392 }
10393 }
10394 }
10395
10396 if (w.mLastHidden && !w.mDrawPending
10397 && !w.mCommitDrawPending
10398 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010399 if (SHOW_TRANSACTIONS) logSurface(w,
10400 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010401 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010402 + " during relayout");
10403 if (showSurfaceRobustlyLocked(w)) {
10404 w.mHasDrawn = true;
10405 w.mLastHidden = false;
10406 } else {
10407 w.mOrientationChanging = false;
10408 }
10409 }
10410 if (w.mSurface != null) {
10411 w.mToken.hasVisible = true;
10412 }
10413 } else {
10414 displayed = true;
10415 }
10416
10417 if (displayed) {
10418 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010419 if (attrs.width == LayoutParams.MATCH_PARENT
10420 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 covered = true;
10422 }
10423 }
10424 if (w.mOrientationChanging) {
10425 if (w.mDrawPending || w.mCommitDrawPending) {
10426 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010427 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428 "Orientation continue waiting for draw in " + w);
10429 } else {
10430 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010431 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010432 "Orientation change complete in " + w);
10433 }
10434 }
10435 w.mToken.hasVisible = true;
10436 }
10437 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010438 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 "Orientation change skips hidden " + w);
10440 w.mOrientationChanging = false;
10441 }
10442
10443 final boolean canBeSeen = w.isDisplayedLw();
10444
10445 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10446 focusDisplayed = true;
10447 }
10448
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010449 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010452 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010453 if (w.mSurface != null) {
10454 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10455 holdScreen = w.mSession;
10456 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010457 if (!syswin && w.mAttrs.screenBrightness >= 0
10458 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010459 screenBrightness = w.mAttrs.screenBrightness;
10460 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010461 if (!syswin && w.mAttrs.buttonBrightness >= 0
10462 && buttonBrightness < 0) {
10463 buttonBrightness = w.mAttrs.buttonBrightness;
10464 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010465 if (canBeSeen
10466 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10467 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10468 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010469 syswin = true;
10470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010472
Dianne Hackborn25994b42009-09-04 14:21:19 -070010473 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10474 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010475 // This window completely covers everything behind it,
10476 // so we want to leave all of them as unblurred (for
10477 // performance reasons).
10478 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010479 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010480 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010481 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010482 obscured = true;
10483 if (mBackgroundFillerSurface == null) {
10484 try {
10485 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010486 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010487 0, dw, dh,
10488 PixelFormat.OPAQUE,
10489 Surface.FX_SURFACE_NORMAL);
10490 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010491 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010492 }
10493 }
10494 try {
10495 mBackgroundFillerSurface.setPosition(0, 0);
10496 mBackgroundFillerSurface.setSize(dw, dh);
10497 // Using the same layer as Dim because they will never be shown at the
10498 // same time.
10499 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10500 mBackgroundFillerSurface.show();
10501 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010502 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010503 }
10504 backgroundFillerShown = true;
10505 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010506 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010507 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010508 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010509 + ": blurring=" + blurring
10510 + " obscured=" + obscured
10511 + " displayed=" + displayed);
10512 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10513 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010514 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010515 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010516 if (mDimAnimator == null) {
10517 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010519 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010520 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 }
10523 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10524 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010525 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010526 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010528 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010529 + mBlurSurface + ": CREATE");
10530 try {
Romain Guy06882f82009-06-10 13:36:04 -070010531 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010532 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 -1, 16, 16,
10534 PixelFormat.OPAQUE,
10535 Surface.FX_SURFACE_BLUR);
10536 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010537 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010538 }
10539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010541 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10542 + mBlurSurface + ": pos=(0,0) (" +
10543 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010544 mBlurSurface.setPosition(0, 0);
10545 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010546 mBlurSurface.setLayer(w.mAnimLayer-2);
10547 if (!mBlurShown) {
10548 try {
10549 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10550 + mBlurSurface + ": SHOW");
10551 mBlurSurface.show();
10552 } catch (RuntimeException e) {
10553 Slog.w(TAG, "Failure showing blur surface", e);
10554 }
10555 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010556 }
10557 }
10558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010559 }
10560 }
10561 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010562
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010563 if (obscuredChanged && mWallpaperTarget == w) {
10564 // This is the wallpaper target and its obscured state
10565 // changed... make sure the current wallaper's visibility
10566 // has been updated accordingly.
10567 updateWallpaperVisibilityLocked();
10568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010569 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010570
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010571 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10572 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010573 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010574 try {
10575 mBackgroundFillerSurface.hide();
10576 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010577 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010578 }
10579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010580
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010581 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010582 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10583 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010584 }
Romain Guy06882f82009-06-10 13:36:04 -070010585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010587 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 + ": HIDE");
10589 try {
10590 mBlurSurface.hide();
10591 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010592 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010593 }
10594 mBlurShown = false;
10595 }
10596
Joe Onorato8a9b2202010-02-26 18:56:32 -080010597 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010598 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010599 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010600 }
10601
10602 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010603
Joe Onorato8a9b2202010-02-26 18:56:32 -080010604 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 "With display frozen, orientationChangeComplete="
10606 + orientationChangeComplete);
10607 if (orientationChangeComplete) {
10608 if (mWindowsFreezingScreen) {
10609 mWindowsFreezingScreen = false;
10610 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10611 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010612 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010613 }
Romain Guy06882f82009-06-10 13:36:04 -070010614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 i = mResizingWindows.size();
10616 if (i > 0) {
10617 do {
10618 i--;
10619 WindowState win = mResizingWindows.get(i);
10620 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010621 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10622 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010623 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010624 boolean configChanged =
10625 win.mConfiguration != mCurConfiguration
10626 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010627 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10628 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10629 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010630 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010631 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010632 + " / " + mCurConfiguration + " / 0x"
10633 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010634 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010635 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 win.mClient.resized(win.mFrame.width(),
10637 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010638 win.mLastVisibleInsets, win.mDrawPending,
10639 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640 win.mContentInsetsChanged = false;
10641 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010642 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010643 } catch (RemoteException e) {
10644 win.mOrientationChanging = false;
10645 }
10646 } while (i > 0);
10647 mResizingWindows.clear();
10648 }
Romain Guy06882f82009-06-10 13:36:04 -070010649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010650 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010651 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 i = mDestroySurface.size();
10653 if (i > 0) {
10654 do {
10655 i--;
10656 WindowState win = mDestroySurface.get(i);
10657 win.mDestroying = false;
10658 if (mInputMethodWindow == win) {
10659 mInputMethodWindow = null;
10660 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010661 if (win == mWallpaperTarget) {
10662 wallpaperDestroyed = true;
10663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 win.destroySurfaceLocked();
10665 } while (i > 0);
10666 mDestroySurface.clear();
10667 }
10668
10669 // Time to remove any exiting tokens?
10670 for (i=mExitingTokens.size()-1; i>=0; i--) {
10671 WindowToken token = mExitingTokens.get(i);
10672 if (!token.hasVisible) {
10673 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010674 if (token.windowType == TYPE_WALLPAPER) {
10675 mWallpaperTokens.remove(token);
10676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010677 }
10678 }
10679
10680 // Time to remove any exiting applications?
10681 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10682 AppWindowToken token = mExitingAppTokens.get(i);
10683 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010684 // Make sure there is no animation running on this token,
10685 // so any windows associated with it will be removed as
10686 // soon as their animations are complete
10687 token.animation = null;
10688 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 mAppTokens.remove(token);
10690 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010691 if (mLastEnterAnimToken == token) {
10692 mLastEnterAnimToken = null;
10693 mLastEnterAnimParams = null;
10694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 }
10696 }
10697
Dianne Hackborna8f60182009-09-01 19:01:50 -070010698 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010699
Dianne Hackborna8f60182009-09-01 19:01:50 -070010700 if (!animating && mAppTransitionRunning) {
10701 // We have finished the animation of an app transition. To do
10702 // this, we have delayed a lot of operations like showing and
10703 // hiding apps, moving apps in Z-order, etc. The app token list
10704 // reflects the correct Z-order, but the window list may now
10705 // be out of sync with it. So here we will just rebuild the
10706 // entire app window list. Fun!
10707 mAppTransitionRunning = false;
10708 needRelayout = true;
10709 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010710 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010711 // Clear information about apps that were moving.
10712 mToBottomApps.clear();
10713 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010715 if (focusDisplayed) {
10716 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10717 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010718 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010719 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010720 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010721 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010722 requestAnimationLocked(0);
10723 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10725 }
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070010726
10727 if (DEBUG_FREEZE) Slog.v(TAG, "Layout: mDisplayFrozen=" + mDisplayFrozen
10728 + " holdScreen=" + holdScreen);
10729 if (!mDisplayFrozen) {
10730 mQueue.setHoldScreenLocked(holdScreen != null);
10731 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10732 mPowerManager.setScreenBrightnessOverride(-1);
10733 } else {
10734 mPowerManager.setScreenBrightnessOverride((int)
10735 (screenBrightness * Power.BRIGHTNESS_ON));
10736 }
10737 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10738 mPowerManager.setButtonBrightnessOverride(-1);
10739 } else {
10740 mPowerManager.setButtonBrightnessOverride((int)
10741 (buttonBrightness * Power.BRIGHTNESS_ON));
10742 }
10743 if (holdScreen != mHoldingScreenOn) {
10744 mHoldingScreenOn = holdScreen;
10745 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10746 mH.sendMessage(m);
10747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010748 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010749
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010750 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010751 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010752 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10753 LocalPowerManager.BUTTON_EVENT, true);
10754 mTurnOnScreen = false;
10755 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010756
10757 // Check to see if we are now in a state where the screen should
10758 // be enabled, because the window obscured flags have changed.
10759 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010760 }
10761
10762 void requestAnimationLocked(long delay) {
10763 if (!mAnimationPending) {
10764 mAnimationPending = true;
10765 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10766 }
10767 }
Romain Guy06882f82009-06-10 13:36:04 -070010768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 /**
10770 * Have the surface flinger show a surface, robustly dealing with
10771 * error conditions. In particular, if there is not enough memory
10772 * to show the surface, then we will try to get rid of other surfaces
10773 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010774 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010775 * @return Returns true if the surface was successfully shown.
10776 */
10777 boolean showSurfaceRobustlyLocked(WindowState win) {
10778 try {
10779 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010780 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010782 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010783 if (DEBUG_VISIBILITY) Slog.v(TAG,
10784 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010785 win.mTurnOnScreen = false;
10786 mTurnOnScreen = true;
10787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010788 }
10789 return true;
10790 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010791 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010792 }
Romain Guy06882f82009-06-10 13:36:04 -070010793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010794 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 return false;
10797 }
Romain Guy06882f82009-06-10 13:36:04 -070010798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10800 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010801
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010802 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010803 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 if (mForceRemoves == null) {
10806 mForceRemoves = new ArrayList<WindowState>();
10807 }
Romain Guy06882f82009-06-10 13:36:04 -070010808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 long callingIdentity = Binder.clearCallingIdentity();
10810 try {
10811 // There was some problem... first, do a sanity check of the
10812 // window list to make sure we haven't left any dangling surfaces
10813 // around.
10814 int N = mWindows.size();
10815 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010816 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 for (int i=0; i<N; i++) {
10818 WindowState ws = (WindowState)mWindows.get(i);
10819 if (ws.mSurface != null) {
10820 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010821 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822 + ws + " surface=" + ws.mSurface
10823 + " token=" + win.mToken
10824 + " pid=" + ws.mSession.mPid
10825 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010826 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010827 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010828 ws.mSurface = null;
10829 mForceRemoves.add(ws);
10830 i--;
10831 N--;
10832 leakedSurface = true;
10833 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010834 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010835 + ws + " surface=" + ws.mSurface
10836 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010837 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010838 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010839 ws.mSurface = null;
10840 leakedSurface = true;
10841 }
10842 }
10843 }
Romain Guy06882f82009-06-10 13:36:04 -070010844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 boolean killedApps = false;
10846 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010847 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010848 SparseIntArray pidCandidates = new SparseIntArray();
10849 for (int i=0; i<N; i++) {
10850 WindowState ws = (WindowState)mWindows.get(i);
10851 if (ws.mSurface != null) {
10852 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10853 }
10854 }
10855 if (pidCandidates.size() > 0) {
10856 int[] pids = new int[pidCandidates.size()];
10857 for (int i=0; i<pids.length; i++) {
10858 pids[i] = pidCandidates.keyAt(i);
10859 }
10860 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010861 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010862 killedApps = true;
10863 }
10864 } catch (RemoteException e) {
10865 }
10866 }
10867 }
Romain Guy06882f82009-06-10 13:36:04 -070010868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010869 if (leakedSurface || killedApps) {
10870 // We managed to reclaim some memory, so get rid of the trouble
10871 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010872 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010874 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010875 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010876 win.mSurface = null;
10877 }
Romain Guy06882f82009-06-10 13:36:04 -070010878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010879 try {
10880 win.mClient.dispatchGetNewSurface();
10881 } catch (RemoteException e) {
10882 }
10883 }
10884 } finally {
10885 Binder.restoreCallingIdentity(callingIdentity);
10886 }
10887 }
Romain Guy06882f82009-06-10 13:36:04 -070010888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010889 private boolean updateFocusedWindowLocked(int mode) {
10890 WindowState newFocus = computeFocusedWindowLocked();
10891 if (mCurrentFocus != newFocus) {
10892 // This check makes sure that we don't already have the focus
10893 // change message pending.
10894 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10895 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010896 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010897 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10898 final WindowState oldFocus = mCurrentFocus;
10899 mCurrentFocus = newFocus;
10900 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010902 final WindowState imWindow = mInputMethodWindow;
10903 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010904 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010906 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10907 mLayoutNeeded = true;
10908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
10910 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010911 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10912 // Client will do the layout, but we need to assign layers
10913 // for handleNewWindowLocked() below.
10914 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 }
10916 }
Romain Guy06882f82009-06-10 13:36:04 -070010917
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010918 if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10919 mKeyWaiter.handleNewWindowLocked(newFocus);
10920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010921 return true;
10922 }
10923 return false;
10924 }
10925
10926 private WindowState computeFocusedWindowLocked() {
10927 WindowState result = null;
10928 WindowState win;
10929
10930 int i = mWindows.size() - 1;
10931 int nextAppIndex = mAppTokens.size()-1;
10932 WindowToken nextApp = nextAppIndex >= 0
10933 ? mAppTokens.get(nextAppIndex) : null;
10934
10935 while (i >= 0) {
10936 win = (WindowState)mWindows.get(i);
10937
Joe Onorato8a9b2202010-02-26 18:56:32 -080010938 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 TAG, "Looking for focus: " + i
10940 + " = " + win
10941 + ", flags=" + win.mAttrs.flags
10942 + ", canReceive=" + win.canReceiveKeys());
10943
10944 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 // If this window's application has been removed, just skip it.
10947 if (thisApp != null && thisApp.removed) {
10948 i--;
10949 continue;
10950 }
Romain Guy06882f82009-06-10 13:36:04 -070010951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010952 // If there is a focused app, don't allow focus to go to any
10953 // windows below it. If this is an application window, step
10954 // through the app tokens until we find its app.
10955 if (thisApp != null && nextApp != null && thisApp != nextApp
10956 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10957 int origAppIndex = nextAppIndex;
10958 while (nextAppIndex > 0) {
10959 if (nextApp == mFocusedApp) {
10960 // Whoops, we are below the focused app... no focus
10961 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010962 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 TAG, "Reached focused app: " + mFocusedApp);
10964 return null;
10965 }
10966 nextAppIndex--;
10967 nextApp = mAppTokens.get(nextAppIndex);
10968 if (nextApp == thisApp) {
10969 break;
10970 }
10971 }
10972 if (thisApp != nextApp) {
10973 // Uh oh, the app token doesn't exist! This shouldn't
10974 // happen, but if it does we can get totally hosed...
10975 // so restart at the original app.
10976 nextAppIndex = origAppIndex;
10977 nextApp = mAppTokens.get(nextAppIndex);
10978 }
10979 }
10980
10981 // Dispatch to this window if it is wants key events.
10982 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010983 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010984 TAG, "Found focus @ " + i + " = " + win);
10985 result = win;
10986 break;
10987 }
10988
10989 i--;
10990 }
10991
10992 return result;
10993 }
10994
10995 private void startFreezingDisplayLocked() {
10996 if (mDisplayFrozen) {
Chris Tate2ad63a92009-03-25 17:36:48 -070010997 // Freezing the display also suspends key event delivery, to
10998 // keep events from going astray while the display is reconfigured.
10999 // If someone has changed orientation again while the screen is
11000 // still frozen, the events will continue to be blocked while the
11001 // successive orientation change is processed. To prevent spurious
11002 // ANRs, we reset the event dispatch timeout in this case.
11003 synchronized (mKeyWaiter) {
11004 mKeyWaiter.mWasFrozen = true;
11005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011006 return;
11007 }
Romain Guy06882f82009-06-10 13:36:04 -070011008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011009 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011012 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 if (mFreezeGcPending != 0) {
11014 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011015 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011016 mH.removeMessages(H.FORCE_GC);
11017 Runtime.getRuntime().gc();
11018 mFreezeGcPending = now;
11019 }
11020 } else {
11021 mFreezeGcPending = now;
11022 }
Romain Guy06882f82009-06-10 13:36:04 -070011023
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011024 if (DEBUG_FREEZE) Slog.v(TAG, "*** FREEZING DISPLAY", new RuntimeException());
11025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 mDisplayFrozen = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011027 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11028 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011029 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030 mAppTransitionReady = true;
11031 }
Romain Guy06882f82009-06-10 13:36:04 -070011032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 if (PROFILE_ORIENTATION) {
11034 File file = new File("/data/system/frozen");
11035 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11036 }
11037 Surface.freezeDisplay(0);
11038 }
Romain Guy06882f82009-06-10 13:36:04 -070011039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011040 private void stopFreezingDisplayLocked() {
11041 if (!mDisplayFrozen) {
11042 return;
11043 }
Romain Guy06882f82009-06-10 13:36:04 -070011044
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011045 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11046 return;
11047 }
11048
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011049 if (DEBUG_FREEZE) Slog.v(TAG, "*** UNFREEZING DISPLAY", new RuntimeException());
11050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011051 mDisplayFrozen = false;
11052 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11053 if (PROFILE_ORIENTATION) {
11054 Debug.stopMethodTracing();
11055 }
11056 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070011057
Chris Tate2ad63a92009-03-25 17:36:48 -070011058 // Reset the key delivery timeout on unfreeze, too. We force a wakeup here
11059 // too because regular key delivery processing should resume immediately.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 synchronized (mKeyWaiter) {
11061 mKeyWaiter.mWasFrozen = true;
11062 mKeyWaiter.notifyAll();
11063 }
11064
Christopher Tateb696aee2010-04-02 19:08:30 -070011065 // While the display is frozen we don't re-compute the orientation
11066 // to avoid inconsistent states. However, something interesting
11067 // could have actually changed during that time so re-evaluate it
11068 // now to catch that.
11069 if (updateOrientationFromAppTokensLocked()) {
11070 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11071 }
11072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011073 // A little kludge: a lot could have happened while the
11074 // display was frozen, so now that we are coming back we
11075 // do a gc so that any remote references the system
11076 // processes holds on others can be released if they are
11077 // no longer needed.
11078 mH.removeMessages(H.FORCE_GC);
11079 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11080 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011082 mScreenFrozenLock.release();
11083 }
Romain Guy06882f82009-06-10 13:36:04 -070011084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011085 @Override
11086 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11087 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11088 != PackageManager.PERMISSION_GRANTED) {
11089 pw.println("Permission Denial: can't dump WindowManager from from pid="
11090 + Binder.getCallingPid()
11091 + ", uid=" + Binder.getCallingUid());
11092 return;
11093 }
Romain Guy06882f82009-06-10 13:36:04 -070011094
Dianne Hackborna2e92262010-03-02 17:19:29 -080011095 pw.println("Input State:");
11096 mQueue.dump(pw, " ");
11097 pw.println(" ");
11098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 synchronized(mWindowMap) {
11100 pw.println("Current Window Manager state:");
11101 for (int i=mWindows.size()-1; i>=0; i--) {
11102 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011103 pw.print(" Window #"); pw.print(i); pw.print(' ');
11104 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011105 w.dump(pw, " ");
11106 }
11107 if (mInputMethodDialogs.size() > 0) {
11108 pw.println(" ");
11109 pw.println(" Input method dialogs:");
11110 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11111 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011112 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011113 }
11114 }
11115 if (mPendingRemove.size() > 0) {
11116 pw.println(" ");
11117 pw.println(" Remove pending for:");
11118 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11119 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011120 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11121 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011122 w.dump(pw, " ");
11123 }
11124 }
11125 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11126 pw.println(" ");
11127 pw.println(" Windows force removing:");
11128 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11129 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011130 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11131 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 w.dump(pw, " ");
11133 }
11134 }
11135 if (mDestroySurface.size() > 0) {
11136 pw.println(" ");
11137 pw.println(" Windows waiting to destroy their surface:");
11138 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11139 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011140 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11141 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011142 w.dump(pw, " ");
11143 }
11144 }
11145 if (mLosingFocus.size() > 0) {
11146 pw.println(" ");
11147 pw.println(" Windows losing focus:");
11148 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11149 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011150 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11151 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011152 w.dump(pw, " ");
11153 }
11154 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011155 if (mResizingWindows.size() > 0) {
11156 pw.println(" ");
11157 pw.println(" Windows waiting to resize:");
11158 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11159 WindowState w = mResizingWindows.get(i);
11160 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11161 pw.print(w); pw.println(":");
11162 w.dump(pw, " ");
11163 }
11164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 if (mSessions.size() > 0) {
11166 pw.println(" ");
11167 pw.println(" All active sessions:");
11168 Iterator<Session> it = mSessions.iterator();
11169 while (it.hasNext()) {
11170 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011171 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011172 s.dump(pw, " ");
11173 }
11174 }
11175 if (mTokenMap.size() > 0) {
11176 pw.println(" ");
11177 pw.println(" All tokens:");
11178 Iterator<WindowToken> it = mTokenMap.values().iterator();
11179 while (it.hasNext()) {
11180 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011181 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 token.dump(pw, " ");
11183 }
11184 }
11185 if (mTokenList.size() > 0) {
11186 pw.println(" ");
11187 pw.println(" Window token list:");
11188 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011189 pw.print(" #"); pw.print(i); pw.print(": ");
11190 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011191 }
11192 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011193 if (mWallpaperTokens.size() > 0) {
11194 pw.println(" ");
11195 pw.println(" Wallpaper tokens:");
11196 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11197 WindowToken token = mWallpaperTokens.get(i);
11198 pw.print(" Wallpaper #"); pw.print(i);
11199 pw.print(' '); pw.print(token); pw.println(':');
11200 token.dump(pw, " ");
11201 }
11202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011203 if (mAppTokens.size() > 0) {
11204 pw.println(" ");
11205 pw.println(" Application tokens in Z order:");
11206 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011207 pw.print(" App #"); pw.print(i); pw.print(": ");
11208 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011209 }
11210 }
11211 if (mFinishedStarting.size() > 0) {
11212 pw.println(" ");
11213 pw.println(" Finishing start of application tokens:");
11214 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11215 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011216 pw.print(" Finished Starting #"); pw.print(i);
11217 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011218 token.dump(pw, " ");
11219 }
11220 }
11221 if (mExitingTokens.size() > 0) {
11222 pw.println(" ");
11223 pw.println(" Exiting tokens:");
11224 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11225 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011226 pw.print(" Exiting #"); pw.print(i);
11227 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011228 token.dump(pw, " ");
11229 }
11230 }
11231 if (mExitingAppTokens.size() > 0) {
11232 pw.println(" ");
11233 pw.println(" Exiting application tokens:");
11234 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11235 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011236 pw.print(" Exiting App #"); pw.print(i);
11237 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011238 token.dump(pw, " ");
11239 }
11240 }
11241 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011242 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11243 pw.print(" mLastFocus="); pw.println(mLastFocus);
11244 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11245 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11246 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011247 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011248 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11249 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11250 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11251 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011252 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11253 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11254 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011255 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11256 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11257 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11258 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011259 if (mDimAnimator != null) {
11260 mDimAnimator.printTo(pw);
11261 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011262 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011263 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011264 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011265 pw.print(mInputMethodAnimLayerAdjustment);
11266 pw.print(" mWallpaperAnimLayerAdjustment=");
11267 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011268 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11269 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011270 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11271 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011272 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11273 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011274 pw.print(" mRotation="); pw.print(mRotation);
11275 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11276 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11277 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11278 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11279 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11280 pw.print(" mNextAppTransition=0x");
11281 pw.print(Integer.toHexString(mNextAppTransition));
11282 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011283 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011284 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011285 if (mNextAppTransitionPackage != null) {
11286 pw.print(" mNextAppTransitionPackage=");
11287 pw.print(mNextAppTransitionPackage);
11288 pw.print(", mNextAppTransitionEnter=0x");
11289 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11290 pw.print(", mNextAppTransitionExit=0x");
11291 pw.print(Integer.toHexString(mNextAppTransitionExit));
11292 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011293 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11294 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011295 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11296 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11297 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11298 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011299 if (mOpeningApps.size() > 0) {
11300 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11301 }
11302 if (mClosingApps.size() > 0) {
11303 pw.print(" mClosingApps="); pw.println(mClosingApps);
11304 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011305 if (mToTopApps.size() > 0) {
11306 pw.print(" mToTopApps="); pw.println(mToTopApps);
11307 }
11308 if (mToBottomApps.size() > 0) {
11309 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11310 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011311 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11312 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011313 pw.println(" KeyWaiter state:");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011314 pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin);
11315 pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
11316 pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished);
11317 pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
11318 pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
11319 pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011320 }
11321 }
11322
11323 public void monitor() {
11324 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011325 synchronized (mKeyguardTokenWatcher) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011326 synchronized (mKeyWaiter) { }
11327 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011328
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011329 public void virtualKeyFeedback(KeyEvent event) {
11330 mPolicy.keyFeedbackFromInput(event);
11331 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011332
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011333 /**
11334 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011335 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011336 */
11337 private static class DimAnimator {
11338 Surface mDimSurface;
11339 boolean mDimShown = false;
11340 float mDimCurrentAlpha;
11341 float mDimTargetAlpha;
11342 float mDimDeltaPerMs;
11343 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011344
11345 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011346
11347 DimAnimator (SurfaceSession session) {
11348 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011349 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011350 + mDimSurface + ": CREATE");
11351 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011352 mDimSurface = new Surface(session, 0,
11353 "DimSurface",
11354 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011355 Surface.FX_SURFACE_DIM);
11356 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011357 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011358 }
11359 }
11360 }
11361
11362 /**
11363 * Show the dim surface.
11364 */
11365 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011366 if (!mDimShown) {
11367 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11368 dw + "x" + dh + ")");
11369 mDimShown = true;
11370 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011371 mLastDimWidth = dw;
11372 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011373 mDimSurface.setPosition(0, 0);
11374 mDimSurface.setSize(dw, dh);
11375 mDimSurface.show();
11376 } catch (RuntimeException e) {
11377 Slog.w(TAG, "Failure showing dim surface", e);
11378 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011379 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11380 mLastDimWidth = dw;
11381 mLastDimHeight = dh;
11382 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011383 }
11384 }
11385
11386 /**
11387 * Set's the dim surface's layer and update dim parameters that will be used in
11388 * {@link updateSurface} after all windows are examined.
11389 */
11390 void updateParameters(WindowState w, long currentTime) {
11391 mDimSurface.setLayer(w.mAnimLayer-1);
11392
11393 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011394 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011395 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011396 if (mDimTargetAlpha != target) {
11397 // If the desired dim level has changed, then
11398 // start an animation to it.
11399 mLastDimAnimTime = currentTime;
11400 long duration = (w.mAnimating && w.mAnimation != null)
11401 ? w.mAnimation.computeDurationHint()
11402 : DEFAULT_DIM_DURATION;
11403 if (target > mDimTargetAlpha) {
11404 // This is happening behind the activity UI,
11405 // so we can make it run a little longer to
11406 // give a stronger impression without disrupting
11407 // the user.
11408 duration *= DIM_DURATION_MULTIPLIER;
11409 }
11410 if (duration < 1) {
11411 // Don't divide by zero
11412 duration = 1;
11413 }
11414 mDimTargetAlpha = target;
11415 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11416 }
11417 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011418
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011419 /**
11420 * Updating the surface's alpha. Returns true if the animation continues, or returns
11421 * false when the animation is finished and the dim surface is hidden.
11422 */
11423 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11424 if (!dimming) {
11425 if (mDimTargetAlpha != 0) {
11426 mLastDimAnimTime = currentTime;
11427 mDimTargetAlpha = 0;
11428 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11429 }
11430 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011431
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011432 boolean animating = false;
11433 if (mLastDimAnimTime != 0) {
11434 mDimCurrentAlpha += mDimDeltaPerMs
11435 * (currentTime-mLastDimAnimTime);
11436 boolean more = true;
11437 if (displayFrozen) {
11438 // If the display is frozen, there is no reason to animate.
11439 more = false;
11440 } else if (mDimDeltaPerMs > 0) {
11441 if (mDimCurrentAlpha > mDimTargetAlpha) {
11442 more = false;
11443 }
11444 } else if (mDimDeltaPerMs < 0) {
11445 if (mDimCurrentAlpha < mDimTargetAlpha) {
11446 more = false;
11447 }
11448 } else {
11449 more = false;
11450 }
11451
11452 // Do we need to continue animating?
11453 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011454 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011455 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11456 mLastDimAnimTime = currentTime;
11457 mDimSurface.setAlpha(mDimCurrentAlpha);
11458 animating = true;
11459 } else {
11460 mDimCurrentAlpha = mDimTargetAlpha;
11461 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011462 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011463 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11464 mDimSurface.setAlpha(mDimCurrentAlpha);
11465 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011466 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011467 + ": HIDE");
11468 try {
11469 mDimSurface.hide();
11470 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011471 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011472 }
11473 mDimShown = false;
11474 }
11475 }
11476 }
11477 return animating;
11478 }
11479
11480 public void printTo(PrintWriter pw) {
11481 pw.print(" mDimShown="); pw.print(mDimShown);
11482 pw.print(" current="); pw.print(mDimCurrentAlpha);
11483 pw.print(" target="); pw.print(mDimTargetAlpha);
11484 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11485 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11486 }
11487 }
11488
11489 /**
11490 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11491 * This is used for opening/closing transition for apps in compatible mode.
11492 */
11493 private static class FadeInOutAnimation extends Animation {
11494 int mWidth;
11495 boolean mFadeIn;
11496
11497 public FadeInOutAnimation(boolean fadeIn) {
11498 setInterpolator(new AccelerateInterpolator());
11499 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11500 mFadeIn = fadeIn;
11501 }
11502
11503 @Override
11504 protected void applyTransformation(float interpolatedTime, Transformation t) {
11505 float x = interpolatedTime;
11506 if (!mFadeIn) {
11507 x = 1.0f - x; // reverse the interpolation for fade out
11508 }
11509 if (x < 0.5) {
11510 // move the window out of the screen.
11511 t.getMatrix().setTranslate(mWidth, 0);
11512 } else {
11513 t.getMatrix().setTranslate(0, 0);// show
11514 t.setAlpha((x - 0.5f) * 2);
11515 }
11516 }
11517
11518 @Override
11519 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11520 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11521 mWidth = width;
11522 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011523
11524 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011525 public int getZAdjustment() {
11526 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011527 }
11528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529}