blob: bf86b2301e9bd7dc0a2123d55524d407e4d59c7b [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;
Jim Miller284b62e2010-06-08 14:27:42 -070058import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070060import android.content.Intent;
61import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.pm.ActivityInfo;
63import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070064import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.content.res.Configuration;
66import android.graphics.Matrix;
67import android.graphics.PixelFormat;
68import android.graphics.Rect;
69import android.graphics.Region;
70import android.os.BatteryStats;
71import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070072import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.Debug;
74import android.os.Handler;
75import android.os.IBinder;
Michael Chan53071d62009-05-13 17:29:48 -070076import android.os.LatencyTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.LocalPowerManager;
78import android.os.Looper;
79import android.os.Message;
80import android.os.Parcel;
81import android.os.ParcelFileDescriptor;
82import android.os.Power;
83import android.os.PowerManager;
84import android.os.Process;
85import android.os.RemoteException;
86import android.os.ServiceManager;
87import android.os.SystemClock;
88import android.os.SystemProperties;
89import android.os.TokenWatcher;
90import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070091import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070093import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080094import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.util.SparseIntArray;
96import android.view.Display;
97import android.view.Gravity;
98import android.view.IApplicationToken;
99import android.view.IOnKeyguardExitResult;
100import android.view.IRotationWatcher;
101import android.view.IWindow;
102import android.view.IWindowManager;
103import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700104import android.view.InputChannel;
105import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.view.KeyEvent;
107import android.view.MotionEvent;
108import android.view.RawInputEvent;
109import android.view.Surface;
110import android.view.SurfaceSession;
111import android.view.View;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700112import android.view.ViewConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.ViewTreeObserver;
114import android.view.WindowManager;
115import android.view.WindowManagerImpl;
116import android.view.WindowManagerPolicy;
117import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700118import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import android.view.animation.Animation;
120import android.view.animation.AnimationUtils;
121import android.view.animation.Transformation;
122
123import java.io.BufferedWriter;
124import java.io.File;
125import java.io.FileDescriptor;
126import java.io.IOException;
127import java.io.OutputStream;
128import java.io.OutputStreamWriter;
129import java.io.PrintWriter;
130import java.io.StringWriter;
131import java.net.Socket;
132import java.util.ArrayList;
133import java.util.HashMap;
134import java.util.HashSet;
135import java.util.Iterator;
136import java.util.List;
137
138/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700139public class WindowManagerService extends IWindowManager.Stub
140 implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 static final String TAG = "WindowManager";
142 static final boolean DEBUG = false;
143 static final boolean DEBUG_FOCUS = false;
144 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800145 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800146 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static final boolean DEBUG_LAYERS = false;
148 static final boolean DEBUG_INPUT = false;
149 static final boolean DEBUG_INPUT_METHOD = false;
150 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700151 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700153 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_APP_TRANSITIONS = false;
155 static final boolean DEBUG_STARTING_WINDOW = false;
156 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700157 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackbornce73c1e2010-04-12 23:11:38 -0700158 static final boolean DEBUG_FREEZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700160 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700161 static final boolean MEASURE_LATENCY = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700162 static final boolean ENABLE_NATIVE_INPUT_DISPATCH =
163 WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH;
Michael Chan53071d62009-05-13 17:29:48 -0700164 static private LatencyTimer lt;
165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean PROFILE_ORIENTATION = false;
167 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700168 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 /** How long to wait for subsequent key repeats, in milliseconds */
171 static final int KEY_REPEAT_DELAY = 50;
172
173 /** How much to multiply the policy's type layer, to reserve room
174 * for multiple windows of the same type and Z-ordering adjustment
175 * with TYPE_LAYER_OFFSET. */
176 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
179 * or below others in the same layer. */
180 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 /** How much to increment the layer for each window, to reserve room
183 * for effect surfaces between them.
184 */
185 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 /** The maximum length we will accept for a loaded animation duration:
188 * this is 10 seconds.
189 */
190 static final int MAX_ANIMATION_DURATION = 10*1000;
191
192 /** Amount of time (in milliseconds) to animate the dim surface from one
193 * value to another, when no window animation is driving it.
194 */
195 static final int DEFAULT_DIM_DURATION = 200;
196
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700197 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
198 * compatible windows.
199 */
200 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 /** Adjustment to time to perform a dim, to make it more dramatic.
203 */
204 static final int DIM_DURATION_MULTIPLIER = 6;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700205
206 // Maximum number of milliseconds to wait for input event injection.
207 // FIXME is this value reasonable?
208 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700209
210 // Default input dispatching timeout in nanoseconds.
211 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700212
Dianne Hackborncfaef692009-06-15 14:24:44 -0700213 static final int INJECT_FAILED = 0;
214 static final int INJECT_SUCCEEDED = 1;
215 static final int INJECT_NO_PERMISSION = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 static final int UPDATE_FOCUS_NORMAL = 0;
218 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
219 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
220 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700221
Michael Chane96440f2009-05-06 10:27:36 -0700222 /** The minimum time between dispatching touch events. */
223 int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
224
225 // Last touch event time
226 long mLastTouchEventTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700227
Michael Chane96440f2009-05-06 10:27:36 -0700228 // Last touch event type
229 int mLastTouchEventType = OTHER_EVENT;
Romain Guy06882f82009-06-10 13:36:04 -0700230
Michael Chane96440f2009-05-06 10:27:36 -0700231 // Time to wait before calling useractivity again. This saves CPU usage
232 // when we get a flood of touch events.
233 static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
234
235 // Last time we call user activity
236 long mLastUserActivityCallTime = 0;
237
Romain Guy06882f82009-06-10 13:36:04 -0700238 // Last time we updated battery stats
Michael Chane96440f2009-05-06 10:27:36 -0700239 long mLastBatteryStatsCallTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700242 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243
244 /**
245 * Condition waited on by {@link #reenableKeyguard} to know the call to
246 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500247 * This is set to true only if mKeyguardTokenWatcher.acquired() has
248 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500250 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251
Jim Miller284b62e2010-06-08 14:27:42 -0700252 private static final int ALLOW_DISABLE_YES = 1;
253 private static final int ALLOW_DISABLE_NO = 0;
254 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
255 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
256
Mike Lockwood983ee092009-11-22 01:42:24 -0500257 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
258 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700260 if (shouldAllowDisableKeyguard()) {
261 mPolicy.enableKeyguard(false);
262 mKeyguardDisabled = true;
263 } else {
264 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 }
267 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700268 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500269 synchronized (mKeyguardTokenWatcher) {
270 mKeyguardDisabled = false;
271 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
273 }
274 };
275
Jim Miller284b62e2010-06-08 14:27:42 -0700276 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
277 @Override
278 public void onReceive(Context context, Intent intent) {
279 mPolicy.enableKeyguard(true);
280 synchronized(mKeyguardTokenWatcher) {
281 // lazily evaluate this next time we're asked to disable keyguard
282 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
283 mKeyguardDisabled = false;
284 }
285 }
286 };
287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 final Context mContext;
289
290 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
295
296 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 /**
301 * All currently active sessions with clients.
302 */
303 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 /**
306 * Mapping from an IWindow IBinder to the server's Window object.
307 * This is also used as the lock for all of our state.
308 */
309 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
310
311 /**
312 * Mapping from a token IBinder to a WindowToken object.
313 */
314 final HashMap<IBinder, WindowToken> mTokenMap =
315 new HashMap<IBinder, WindowToken>();
316
317 /**
318 * The same tokens as mTokenMap, stored in a list for efficient iteration
319 * over them.
320 */
321 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 /**
324 * Window tokens that are in the process of exiting, but still
325 * on screen for animations.
326 */
327 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
328
329 /**
330 * Z-ordered (bottom-most first) list of all application tokens, for
331 * controlling the ordering of windows in different applications. This
332 * contains WindowToken objects.
333 */
334 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
335
336 /**
337 * Application tokens that are in the process of exiting, but still
338 * on screen for animations.
339 */
340 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
341
342 /**
343 * List of window tokens that have finished starting their application,
344 * and now need to have the policy remove their windows.
345 */
346 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
347
348 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700349 * This was the app token that was used to retrieve the last enter
350 * animation. It will be used for the next exit animation.
351 */
352 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800353
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700354 /**
355 * These were the layout params used to retrieve the last enter animation.
356 * They will be used for the next exit animation.
357 */
358 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800359
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700360 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 * Z-ordered (bottom-most first) list of all Window objects.
362 */
363 final ArrayList mWindows = new ArrayList();
364
365 /**
366 * Windows that are being resized. Used so we can tell the client about
367 * the resize after closing the transaction in which we resized the
368 * underlying surface.
369 */
370 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
371
372 /**
373 * Windows whose animations have ended and now must be removed.
374 */
375 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
376
377 /**
378 * Windows whose surface should be destroyed.
379 */
380 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
381
382 /**
383 * Windows that have lost input focus and are waiting for the new
384 * focus window to be displayed before they are told about this.
385 */
386 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
387
388 /**
389 * This is set when we have run out of memory, and will either be an empty
390 * list or contain windows that need to be force removed.
391 */
392 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700397 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 Surface mBlurSurface;
399 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 final float[] mTmpFloats = new float[9];
404
405 boolean mSafeMode;
406 boolean mDisplayEnabled = false;
407 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700408 int mInitialDisplayWidth = 0;
409 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 int mRotation = 0;
411 int mRequestedRotation = 0;
412 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700413 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 ArrayList<IRotationWatcher> mRotationWatchers
415 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 boolean mLayoutNeeded = true;
418 boolean mAnimationPending = false;
419 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800420 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 boolean mWindowsFreezingScreen = false;
422 long mFreezeGcPending = 0;
423 int mAppsFreezingScreen = 0;
424
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800425 int mLayoutSeq = 0;
426
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800427 // State while inside of layoutAndPlaceSurfacesLocked().
428 boolean mFocusMayChange;
429
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800430 Configuration mCurConfiguration = new Configuration();
431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 // This is held as long as we have the screen frozen, to give us time to
433 // perform a rotation animation when turning off shows the lock screen which
434 // changes the orientation.
435 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 // State management of app transitions. When we are preparing for a
438 // transition, mNextAppTransition will be the kind of transition to
439 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
440 // mOpeningApps and mClosingApps are the lists of tokens that will be
441 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700442 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700443 String mNextAppTransitionPackage;
444 int mNextAppTransitionEnter;
445 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700447 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 boolean mAppTransitionTimeout = false;
449 boolean mStartingIconInTransition = false;
450 boolean mSkipAppTransitionAnimation = false;
451 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
452 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700453 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
454 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 H mH = new H();
459
460 WindowState mCurrentFocus = null;
461 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 // This just indicates the window the input method is on top of, not
464 // necessarily the window its input is going to.
465 WindowState mInputMethodTarget = null;
466 WindowState mUpcomingInputMethodTarget = null;
467 boolean mInputMethodTargetWaitingAnim;
468 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 WindowState mInputMethodWindow = null;
471 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
472
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700473 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800474
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700475 // If non-null, this is the currently visible window that is associated
476 // with the wallpaper.
477 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700478 // If non-null, we are in the middle of animating from one wallpaper target
479 // to another, and this is the lower one in Z-order.
480 WindowState mLowerWallpaperTarget = null;
481 // If non-null, we are in the middle of animating from one wallpaper target
482 // to another, and this is the higher one in Z-order.
483 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700484 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700485 float mLastWallpaperX = -1;
486 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800487 float mLastWallpaperXStep = -1;
488 float mLastWallpaperYStep = -1;
Dianne Hackborn6adba242009-11-10 11:10:09 -0800489 boolean mSendingPointersToWallpaper = false;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700490 // This is set when we are waiting for a wallpaper to tell us it is done
491 // changing its scroll position.
492 WindowState mWaitingOnWallpaper;
493 // The last time we had a timeout when waiting for a wallpaper.
494 long mLastWallpaperTimeoutTime;
495 // We give a wallpaper up to 150ms to finish scrolling.
496 static final long WALLPAPER_TIMEOUT = 150;
497 // Time we wait after a timeout before trying to wait again.
498 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 AppWindowToken mFocusedApp = null;
501
502 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 float mWindowAnimationScale = 1.0f;
505 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 final KeyWaiter mKeyWaiter = new KeyWaiter();
508 final KeyQ mQueue;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700509 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 final InputDispatcherThread mInputThread;
511
512 // Who is holding the screen on.
513 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700514 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700515
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700516 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 /**
519 * Whether the UI is currently running in touch mode (not showing
520 * navigational focus because the user is directly pressing the screen).
521 */
522 boolean mInTouchMode = false;
523
524 private ViewServer mViewServer;
525
526 final Rect mTempRect = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -0700527
Dianne Hackbornc485a602009-03-24 22:39:49 -0700528 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700529 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700530
531 // The frame use to limit the size of the app running in compatibility mode.
532 Rect mCompatibleScreenFrame = new Rect();
533 // The surface used to fill the outer rim of the app running in compatibility mode.
534 Surface mBackgroundFillerSurface = null;
535 boolean mBackgroundFillerShown = false;
536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 public static WindowManagerService main(Context context,
538 PowerManagerService pm, boolean haveInputMethods) {
539 WMThread thr = new WMThread(context, pm, haveInputMethods);
540 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 synchronized (thr) {
543 while (thr.mService == null) {
544 try {
545 thr.wait();
546 } catch (InterruptedException e) {
547 }
548 }
549 }
Romain Guy06882f82009-06-10 13:36:04 -0700550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 return thr.mService;
552 }
Romain Guy06882f82009-06-10 13:36:04 -0700553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 static class WMThread extends Thread {
555 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 private final Context mContext;
558 private final PowerManagerService mPM;
559 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 public WMThread(Context context, PowerManagerService pm,
562 boolean haveInputMethods) {
563 super("WindowManager");
564 mContext = context;
565 mPM = pm;
566 mHaveInputMethods = haveInputMethods;
567 }
Romain Guy06882f82009-06-10 13:36:04 -0700568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 public void run() {
570 Looper.prepare();
571 WindowManagerService s = new WindowManagerService(mContext, mPM,
572 mHaveInputMethods);
573 android.os.Process.setThreadPriority(
574 android.os.Process.THREAD_PRIORITY_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -0700575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 synchronized (this) {
577 mService = s;
578 notifyAll();
579 }
Romain Guy06882f82009-06-10 13:36:04 -0700580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 Looper.loop();
582 }
583 }
584
585 static class PolicyThread extends Thread {
586 private final WindowManagerPolicy mPolicy;
587 private final WindowManagerService mService;
588 private final Context mContext;
589 private final PowerManagerService mPM;
590 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 public PolicyThread(WindowManagerPolicy policy,
593 WindowManagerService service, Context context,
594 PowerManagerService pm) {
595 super("WindowManagerPolicy");
596 mPolicy = policy;
597 mService = service;
598 mContext = context;
599 mPM = pm;
600 }
Romain Guy06882f82009-06-10 13:36:04 -0700601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 public void run() {
603 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800604 WindowManagerPolicyThread.set(this, Looper.myLooper());
605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800607 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 android.os.Process.setThreadPriority(
609 android.os.Process.THREAD_PRIORITY_FOREGROUND);
610 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 synchronized (this) {
613 mRunning = true;
614 notifyAll();
615 }
Romain Guy06882f82009-06-10 13:36:04 -0700616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 Looper.loop();
618 }
619 }
620
621 private WindowManagerService(Context context, PowerManagerService pm,
622 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700623 if (MEASURE_LATENCY) {
624 lt = new LatencyTimer(100, 1000);
625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 mContext = context;
628 mHaveInputMethods = haveInputMethods;
629 mLimitedAlphaCompositing = context.getResources().getBoolean(
630 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 mPowerManager = pm;
633 mPowerManager.setPolicy(mPolicy);
634 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
635 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
636 "SCREEN_FROZEN");
637 mScreenFrozenLock.setReferenceCounted(false);
638
639 mActivityManager = ActivityManagerNative.getDefault();
640 mBatteryStats = BatteryStatsService.getService();
641
642 // Get persisted window scale setting
643 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
644 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
645 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
646 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700647
Jim Miller284b62e2010-06-08 14:27:42 -0700648 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
649 IntentFilter filter = new IntentFilter();
650 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
651 mContext.registerReceiver(mBroadcastReceiver, filter);
652
Michael Chan9f028e62009-08-04 17:37:46 -0700653 int max_events_per_sec = 35;
654 try {
655 max_events_per_sec = Integer.parseInt(SystemProperties
656 .get("windowsmgr.max_events_per_sec"));
657 if (max_events_per_sec < 1) {
658 max_events_per_sec = 35;
659 }
660 } catch (NumberFormatException e) {
661 }
662 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
663
Jeff Brown46b9ac02010-04-22 18:58:52 -0700664 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
665 "KEEP_SCREEN_ON_FLAG");
666 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667
Jeff Brown46b9ac02010-04-22 18:58:52 -0700668 if (ENABLE_NATIVE_INPUT_DISPATCH) {
669 mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager);
670 } else {
671 mInputManager = null;
672 }
673 mQueue = new KeyQ();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 mInputThread = new InputDispatcherThread();
Romain Guy06882f82009-06-10 13:36:04 -0700675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
677 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679 synchronized (thr) {
680 while (!thr.mRunning) {
681 try {
682 thr.wait();
683 } catch (InterruptedException e) {
684 }
685 }
686 }
Romain Guy06882f82009-06-10 13:36:04 -0700687
Jeff Brown46b9ac02010-04-22 18:58:52 -0700688 if (ENABLE_NATIVE_INPUT_DISPATCH) {
689 mInputManager.start();
690 } else {
691 mInputThread.start();
692 }
Romain Guy06882f82009-06-10 13:36:04 -0700693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 // Add ourself to the Watchdog monitors.
695 Watchdog.getInstance().addMonitor(this);
696 }
697
698 @Override
699 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
700 throws RemoteException {
701 try {
702 return super.onTransact(code, data, reply, flags);
703 } catch (RuntimeException e) {
704 // The window manager only throws security exceptions, so let's
705 // log all others.
706 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800707 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 }
709 throw e;
710 }
711 }
712
713 private void placeWindowAfter(Object pos, WindowState window) {
714 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800715 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 TAG, "Adding window " + window + " at "
717 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
718 mWindows.add(i+1, window);
719 }
720
721 private void placeWindowBefore(Object pos, WindowState window) {
722 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800723 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 TAG, "Adding window " + window + " at "
725 + i + " of " + mWindows.size() + " (before " + pos + ")");
726 mWindows.add(i, window);
727 }
728
729 //This method finds out the index of a window that has the same app token as
730 //win. used for z ordering the windows in mWindows
731 private int findIdxBasedOnAppTokens(WindowState win) {
732 //use a local variable to cache mWindows
733 ArrayList localmWindows = mWindows;
734 int jmax = localmWindows.size();
735 if(jmax == 0) {
736 return -1;
737 }
738 for(int j = (jmax-1); j >= 0; j--) {
739 WindowState wentry = (WindowState)localmWindows.get(j);
740 if(wentry.mAppToken == win.mAppToken) {
741 return j;
742 }
743 }
744 return -1;
745 }
Romain Guy06882f82009-06-10 13:36:04 -0700746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
748 final IWindow client = win.mClient;
749 final WindowToken token = win.mToken;
750 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 final int N = localmWindows.size();
753 final WindowState attached = win.mAttachedWindow;
754 int i;
755 if (attached == null) {
756 int tokenWindowsPos = token.windows.size();
757 if (token.appWindowToken != null) {
758 int index = tokenWindowsPos-1;
759 if (index >= 0) {
760 // If this application has existing windows, we
761 // simply place the new window on top of them... but
762 // keep the starting window on top.
763 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
764 // Base windows go behind everything else.
765 placeWindowBefore(token.windows.get(0), win);
766 tokenWindowsPos = 0;
767 } else {
768 AppWindowToken atoken = win.mAppToken;
769 if (atoken != null &&
770 token.windows.get(index) == atoken.startingWindow) {
771 placeWindowBefore(token.windows.get(index), win);
772 tokenWindowsPos--;
773 } else {
774 int newIdx = findIdxBasedOnAppTokens(win);
775 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700776 //there is a window above this one associated with the same
777 //apptoken note that the window could be a floating window
778 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800780 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700781 TAG, "Adding window " + win + " at "
782 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 localmWindows.add(newIdx+1, win);
Romain Guy06882f82009-06-10 13:36:04 -0700784 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 }
786 }
787 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800788 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 TAG, "Figuring out where to add app window "
790 + client.asBinder() + " (token=" + token + ")");
791 // Figure out where the window should go, based on the
792 // order of applications.
793 final int NA = mAppTokens.size();
794 Object pos = null;
795 for (i=NA-1; i>=0; i--) {
796 AppWindowToken t = mAppTokens.get(i);
797 if (t == token) {
798 i--;
799 break;
800 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800801
Dianne Hackborna8f60182009-09-01 19:01:50 -0700802 // We haven't reached the token yet; if this token
803 // is not going to the bottom and has windows, we can
804 // use it as an anchor for when we do reach the token.
805 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 pos = t.windows.get(0);
807 }
808 }
809 // We now know the index into the apps. If we found
810 // an app window above, that gives us the position; else
811 // we need to look some more.
812 if (pos != null) {
813 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700814 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 mTokenMap.get(((WindowState)pos).mClient.asBinder());
816 if (atoken != null) {
817 final int NC = atoken.windows.size();
818 if (NC > 0) {
819 WindowState bottom = atoken.windows.get(0);
820 if (bottom.mSubLayer < 0) {
821 pos = bottom;
822 }
823 }
824 }
825 placeWindowBefore(pos, win);
826 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700827 // Continue looking down until we find the first
828 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 while (i >= 0) {
830 AppWindowToken t = mAppTokens.get(i);
831 final int NW = t.windows.size();
832 if (NW > 0) {
833 pos = t.windows.get(NW-1);
834 break;
835 }
836 i--;
837 }
838 if (pos != null) {
839 // Move in front of any windows attached to this
840 // one.
841 WindowToken atoken =
842 mTokenMap.get(((WindowState)pos).mClient.asBinder());
843 if (atoken != null) {
844 final int NC = atoken.windows.size();
845 if (NC > 0) {
846 WindowState top = atoken.windows.get(NC-1);
847 if (top.mSubLayer >= 0) {
848 pos = top;
849 }
850 }
851 }
852 placeWindowAfter(pos, win);
853 } else {
854 // Just search for the start of this layer.
855 final int myLayer = win.mBaseLayer;
856 for (i=0; i<N; i++) {
857 WindowState w = (WindowState)localmWindows.get(i);
858 if (w.mBaseLayer > myLayer) {
859 break;
860 }
861 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800862 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700863 TAG, "Adding window " + win + " at "
864 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 localmWindows.add(i, win);
866 }
867 }
868 }
869 } else {
870 // Figure out where window should go, based on layer.
871 final int myLayer = win.mBaseLayer;
872 for (i=N-1; i>=0; i--) {
873 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
874 i++;
875 break;
876 }
877 }
878 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800879 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700880 TAG, "Adding window " + win + " at "
881 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 localmWindows.add(i, win);
883 }
884 if (addToToken) {
885 token.windows.add(tokenWindowsPos, win);
886 }
887
888 } else {
889 // Figure out this window's ordering relative to the window
890 // it is attached to.
891 final int NA = token.windows.size();
892 final int sublayer = win.mSubLayer;
893 int largestSublayer = Integer.MIN_VALUE;
894 WindowState windowWithLargestSublayer = null;
895 for (i=0; i<NA; i++) {
896 WindowState w = token.windows.get(i);
897 final int wSublayer = w.mSubLayer;
898 if (wSublayer >= largestSublayer) {
899 largestSublayer = wSublayer;
900 windowWithLargestSublayer = w;
901 }
902 if (sublayer < 0) {
903 // For negative sublayers, we go below all windows
904 // in the same sublayer.
905 if (wSublayer >= sublayer) {
906 if (addToToken) {
907 token.windows.add(i, win);
908 }
909 placeWindowBefore(
910 wSublayer >= 0 ? attached : w, win);
911 break;
912 }
913 } else {
914 // For positive sublayers, we go above all windows
915 // in the same sublayer.
916 if (wSublayer > sublayer) {
917 if (addToToken) {
918 token.windows.add(i, win);
919 }
920 placeWindowBefore(w, win);
921 break;
922 }
923 }
924 }
925 if (i >= NA) {
926 if (addToToken) {
927 token.windows.add(win);
928 }
929 if (sublayer < 0) {
930 placeWindowBefore(attached, win);
931 } else {
932 placeWindowAfter(largestSublayer >= 0
933 ? windowWithLargestSublayer
934 : attached,
935 win);
936 }
937 }
938 }
Romain Guy06882f82009-06-10 13:36:04 -0700939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 if (win.mAppToken != null && addToToken) {
941 win.mAppToken.allAppWindows.add(win);
942 }
943 }
Romain Guy06882f82009-06-10 13:36:04 -0700944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 static boolean canBeImeTarget(WindowState w) {
946 final int fl = w.mAttrs.flags
947 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
948 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
949 return w.isVisibleOrAdding();
950 }
951 return false;
952 }
Romain Guy06882f82009-06-10 13:36:04 -0700953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
955 final ArrayList localmWindows = mWindows;
956 final int N = localmWindows.size();
957 WindowState w = null;
958 int i = N;
959 while (i > 0) {
960 i--;
961 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700962
Joe Onorato8a9b2202010-02-26 18:56:32 -0800963 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 // + Integer.toHexString(w.mAttrs.flags));
965 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 // Yet more tricksyness! If this window is a "starting"
969 // window, we do actually want to be on top of it, but
970 // it is not -really- where input will go. So if the caller
971 // is not actually looking to move the IME, look down below
972 // for a real window to target...
973 if (!willMove
974 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
975 && i > 0) {
976 WindowState wb = (WindowState)localmWindows.get(i-1);
977 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
978 i--;
979 w = wb;
980 }
981 }
982 break;
983 }
984 }
Romain Guy06882f82009-06-10 13:36:04 -0700985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700987
Joe Onorato8a9b2202010-02-26 18:56:32 -0800988 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 if (willMove && w != null) {
992 final WindowState curTarget = mInputMethodTarget;
993 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 // Now some fun for dealing with window animations that
996 // modify the Z order. We need to look at all windows below
997 // the current target that are in this app, finding the highest
998 // visible one in layering.
999 AppWindowToken token = curTarget.mAppToken;
1000 WindowState highestTarget = null;
1001 int highestPos = 0;
1002 if (token.animating || token.animation != null) {
1003 int pos = 0;
1004 pos = localmWindows.indexOf(curTarget);
1005 while (pos >= 0) {
1006 WindowState win = (WindowState)localmWindows.get(pos);
1007 if (win.mAppToken != token) {
1008 break;
1009 }
1010 if (!win.mRemoved) {
1011 if (highestTarget == null || win.mAnimLayer >
1012 highestTarget.mAnimLayer) {
1013 highestTarget = win;
1014 highestPos = pos;
1015 }
1016 }
1017 pos--;
1018 }
1019 }
Romain Guy06882f82009-06-10 13:36:04 -07001020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001022 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 + mNextAppTransition + " " + highestTarget
1024 + " animating=" + highestTarget.isAnimating()
1025 + " layer=" + highestTarget.mAnimLayer
1026 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001027
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001028 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 // If we are currently setting up for an animation,
1030 // hold everything until we can find out what will happen.
1031 mInputMethodTargetWaitingAnim = true;
1032 mInputMethodTarget = highestTarget;
1033 return highestPos + 1;
1034 } else if (highestTarget.isAnimating() &&
1035 highestTarget.mAnimLayer > w.mAnimLayer) {
1036 // If the window we are currently targeting is involved
1037 // with an animation, and it is on top of the next target
1038 // we will be over, then hold off on moving until
1039 // that is done.
1040 mInputMethodTarget = highestTarget;
1041 return highestPos + 1;
1042 }
1043 }
1044 }
1045 }
Romain Guy06882f82009-06-10 13:36:04 -07001046
Joe Onorato8a9b2202010-02-26 18:56:32 -08001047 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 if (w != null) {
1049 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001050 if (DEBUG_INPUT_METHOD) {
1051 RuntimeException e = null;
1052 if (!HIDE_STACK_CRAWLS) {
1053 e = new RuntimeException();
1054 e.fillInStackTrace();
1055 }
1056 Slog.w(TAG, "Moving IM target from "
1057 + mInputMethodTarget + " to " + w, e);
1058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059 mInputMethodTarget = w;
1060 if (w.mAppToken != null) {
1061 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1062 } else {
1063 setInputMethodAnimLayerAdjustment(0);
1064 }
1065 }
1066 return i+1;
1067 }
1068 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001069 if (DEBUG_INPUT_METHOD) {
1070 RuntimeException e = null;
1071 if (!HIDE_STACK_CRAWLS) {
1072 e = new RuntimeException();
1073 e.fillInStackTrace();
1074 }
1075 Slog.w(TAG, "Moving IM target from "
1076 + mInputMethodTarget + " to null", e);
1077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 mInputMethodTarget = null;
1079 setInputMethodAnimLayerAdjustment(0);
1080 }
1081 return -1;
1082 }
Romain Guy06882f82009-06-10 13:36:04 -07001083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 void addInputMethodWindowToListLocked(WindowState win) {
1085 int pos = findDesiredInputMethodWindowIndexLocked(true);
1086 if (pos >= 0) {
1087 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001088 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001089 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 mWindows.add(pos, win);
1091 moveInputMethodDialogsLocked(pos+1);
1092 return;
1093 }
1094 win.mTargetAppToken = null;
1095 addWindowToListInOrderLocked(win, true);
1096 moveInputMethodDialogsLocked(pos);
1097 }
Romain Guy06882f82009-06-10 13:36:04 -07001098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001100 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 mInputMethodAnimLayerAdjustment = adj;
1102 WindowState imw = mInputMethodWindow;
1103 if (imw != null) {
1104 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001105 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 + " anim layer: " + imw.mAnimLayer);
1107 int wi = imw.mChildWindows.size();
1108 while (wi > 0) {
1109 wi--;
1110 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1111 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001112 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 + " anim layer: " + cw.mAnimLayer);
1114 }
1115 }
1116 int di = mInputMethodDialogs.size();
1117 while (di > 0) {
1118 di --;
1119 imw = mInputMethodDialogs.get(di);
1120 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001121 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 + " anim layer: " + imw.mAnimLayer);
1123 }
1124 }
Romain Guy06882f82009-06-10 13:36:04 -07001125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1127 int wpos = mWindows.indexOf(win);
1128 if (wpos >= 0) {
1129 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001130 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 mWindows.remove(wpos);
1132 int NC = win.mChildWindows.size();
1133 while (NC > 0) {
1134 NC--;
1135 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1136 int cpos = mWindows.indexOf(cw);
1137 if (cpos >= 0) {
1138 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001139 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001140 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 mWindows.remove(cpos);
1142 }
1143 }
1144 }
1145 return interestingPos;
1146 }
Romain Guy06882f82009-06-10 13:36:04 -07001147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 private void reAddWindowToListInOrderLocked(WindowState win) {
1149 addWindowToListInOrderLocked(win, false);
1150 // This is a hack to get all of the child windows added as well
1151 // at the right position. Child windows should be rare and
1152 // this case should be rare, so it shouldn't be that big a deal.
1153 int wpos = mWindows.indexOf(win);
1154 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001155 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001156 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 mWindows.remove(wpos);
1158 reAddWindowLocked(wpos, win);
1159 }
1160 }
Romain Guy06882f82009-06-10 13:36:04 -07001161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 void logWindowList(String prefix) {
1163 int N = mWindows.size();
1164 while (N > 0) {
1165 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001166 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 }
1168 }
Romain Guy06882f82009-06-10 13:36:04 -07001169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 void moveInputMethodDialogsLocked(int pos) {
1171 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001174 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 for (int i=0; i<N; i++) {
1176 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1177 }
1178 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001179 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 logWindowList(" ");
1181 }
Romain Guy06882f82009-06-10 13:36:04 -07001182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 if (pos >= 0) {
1184 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1185 if (pos < mWindows.size()) {
1186 WindowState wp = (WindowState)mWindows.get(pos);
1187 if (wp == mInputMethodWindow) {
1188 pos++;
1189 }
1190 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001191 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 for (int i=0; i<N; i++) {
1193 WindowState win = dialogs.get(i);
1194 win.mTargetAppToken = targetAppToken;
1195 pos = reAddWindowLocked(pos, win);
1196 }
1197 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001198 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 logWindowList(" ");
1200 }
1201 return;
1202 }
1203 for (int i=0; i<N; i++) {
1204 WindowState win = dialogs.get(i);
1205 win.mTargetAppToken = null;
1206 reAddWindowToListInOrderLocked(win);
1207 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001208 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 logWindowList(" ");
1210 }
1211 }
1212 }
Romain Guy06882f82009-06-10 13:36:04 -07001213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1215 final WindowState imWin = mInputMethodWindow;
1216 final int DN = mInputMethodDialogs.size();
1217 if (imWin == null && DN == 0) {
1218 return false;
1219 }
Romain Guy06882f82009-06-10 13:36:04 -07001220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1222 if (imPos >= 0) {
1223 // In this case, the input method windows are to be placed
1224 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 // First check to see if the input method windows are already
1227 // located here, and contiguous.
1228 final int N = mWindows.size();
1229 WindowState firstImWin = imPos < N
1230 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 // Figure out the actual input method window that should be
1233 // at the bottom of their stack.
1234 WindowState baseImWin = imWin != null
1235 ? imWin : mInputMethodDialogs.get(0);
1236 if (baseImWin.mChildWindows.size() > 0) {
1237 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1238 if (cw.mSubLayer < 0) baseImWin = cw;
1239 }
Romain Guy06882f82009-06-10 13:36:04 -07001240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 if (firstImWin == baseImWin) {
1242 // The windows haven't moved... but are they still contiguous?
1243 // First find the top IM window.
1244 int pos = imPos+1;
1245 while (pos < N) {
1246 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1247 break;
1248 }
1249 pos++;
1250 }
1251 pos++;
1252 // Now there should be no more input method windows above.
1253 while (pos < N) {
1254 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1255 break;
1256 }
1257 pos++;
1258 }
1259 if (pos >= N) {
1260 // All is good!
1261 return false;
1262 }
1263 }
Romain Guy06882f82009-06-10 13:36:04 -07001264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 if (imWin != null) {
1266 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001267 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 logWindowList(" ");
1269 }
1270 imPos = tmpRemoveWindowLocked(imPos, imWin);
1271 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001272 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 logWindowList(" ");
1274 }
1275 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1276 reAddWindowLocked(imPos, imWin);
1277 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001278 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 logWindowList(" ");
1280 }
1281 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1282 } else {
1283 moveInputMethodDialogsLocked(imPos);
1284 }
Romain Guy06882f82009-06-10 13:36:04 -07001285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 } else {
1287 // In this case, the input method windows go in a fixed layer,
1288 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001291 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 tmpRemoveWindowLocked(0, imWin);
1293 imWin.mTargetAppToken = null;
1294 reAddWindowToListInOrderLocked(imWin);
1295 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001296 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 logWindowList(" ");
1298 }
1299 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1300 } else {
1301 moveInputMethodDialogsLocked(-1);;
1302 }
Romain Guy06882f82009-06-10 13:36:04 -07001303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 }
Romain Guy06882f82009-06-10 13:36:04 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 if (needAssignLayers) {
1307 assignLayersLocked();
1308 }
Romain Guy06882f82009-06-10 13:36:04 -07001309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 return true;
1311 }
Romain Guy06882f82009-06-10 13:36:04 -07001312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 void adjustInputMethodDialogsLocked() {
1314 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1315 }
Romain Guy06882f82009-06-10 13:36:04 -07001316
Dianne Hackborn25994b42009-09-04 14:21:19 -07001317 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001318 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001319 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1320 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1321 ? wallpaperTarget.mAppToken.animation : null)
1322 + " upper=" + mUpperWallpaperTarget
1323 + " lower=" + mLowerWallpaperTarget);
1324 return (wallpaperTarget != null
1325 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1326 && wallpaperTarget.mAppToken.animation != null)))
1327 || mUpperWallpaperTarget != null
1328 || mLowerWallpaperTarget != null;
1329 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001330
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001331 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1332 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001333
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001334 int adjustWallpaperWindowsLocked() {
1335 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001336
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001337 final int dw = mDisplay.getWidth();
1338 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001339
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001340 // First find top-most window that has asked to be on top of the
1341 // wallpaper; all wallpapers go behind it.
1342 final ArrayList localmWindows = mWindows;
1343 int N = localmWindows.size();
1344 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001345 WindowState foundW = null;
1346 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001347 WindowState topCurW = null;
1348 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001349 int i = N;
1350 while (i > 0) {
1351 i--;
1352 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001353 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1354 if (topCurW == null) {
1355 topCurW = w;
1356 topCurI = i;
1357 }
1358 continue;
1359 }
1360 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001361 if (w.mAppToken != null) {
1362 // If this window's app token is hidden and not animating,
1363 // it is of no interest to us.
1364 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001365 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001366 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001367 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001368 continue;
1369 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001370 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001371 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001372 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1373 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001374 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001375 && (mWallpaperTarget == w
1376 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001377 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001378 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001379 foundW = w;
1380 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001381 if (w == mWallpaperTarget && ((w.mAppToken != null
1382 && w.mAppToken.animation != null)
1383 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001384 // The current wallpaper target is animating, so we'll
1385 // look behind it for another possible target and figure
1386 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001387 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001388 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001389 continue;
1390 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001391 break;
1392 }
1393 }
1394
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001395 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001396 // If we are currently waiting for an app transition, and either
1397 // the current target or the next target are involved with it,
1398 // then hold off on doing anything with the wallpaper.
1399 // Note that we are checking here for just whether the target
1400 // is part of an app token... which is potentially overly aggressive
1401 // (the app token may not be involved in the transition), but good
1402 // enough (we'll just wait until whatever transition is pending
1403 // executes).
1404 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001405 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001406 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001407 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001408 }
1409 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001410 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001411 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001412 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001413 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001414 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001415
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001416 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001417 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001418 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001419 + " oldTarget: " + mWallpaperTarget);
1420 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001421
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001422 mLowerWallpaperTarget = null;
1423 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001424
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001425 WindowState oldW = mWallpaperTarget;
1426 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001427
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001428 // Now what is happening... if the current and new targets are
1429 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001430 if (foundW != null && oldW != null) {
1431 boolean oldAnim = oldW.mAnimation != null
1432 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1433 boolean foundAnim = foundW.mAnimation != null
1434 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001435 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001436 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001437 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001438 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001439 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001440 int oldI = localmWindows.indexOf(oldW);
1441 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001442 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001443 }
1444 if (oldI >= 0) {
1445 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001446 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001447 + "=" + oldW + "; new#" + foundI
1448 + "=" + foundW);
1449 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001450
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001451 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001452 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001453 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001454 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001455 }
1456 mWallpaperTarget = oldW;
1457 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001458
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001459 // Now set the upper and lower wallpaper targets
1460 // correctly, and make sure that we are positioning
1461 // the wallpaper below the lower.
1462 if (foundI > oldI) {
1463 // The new target is on top of the old one.
1464 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001465 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001466 }
1467 mUpperWallpaperTarget = foundW;
1468 mLowerWallpaperTarget = oldW;
1469 foundW = oldW;
1470 foundI = oldI;
1471 } else {
1472 // The new target is below the old one.
1473 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001474 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001475 }
1476 mUpperWallpaperTarget = oldW;
1477 mLowerWallpaperTarget = foundW;
1478 }
1479 }
1480 }
1481 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001482
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001483 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001484 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001485 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1486 || (mLowerWallpaperTarget.mAppToken != null
1487 && mLowerWallpaperTarget.mAppToken.animation != null);
1488 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1489 || (mUpperWallpaperTarget.mAppToken != null
1490 && mUpperWallpaperTarget.mAppToken.animation != null);
1491 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001492 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001493 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001494 }
1495 mLowerWallpaperTarget = null;
1496 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001497 }
1498 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001499
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001500 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001501 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001502 // The window is visible to the compositor... but is it visible
1503 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001504 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001505 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001506
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001507 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001508 // its layer adjustment. Only do this if we are not transfering
1509 // between two wallpaper targets.
1510 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001511 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001512 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001513
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001514 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1515 * TYPE_LAYER_MULTIPLIER
1516 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001517
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001518 // Now w is the window we are supposed to be behind... but we
1519 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001520 // AND any starting window associated with it, AND below the
1521 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001522 while (foundI > 0) {
1523 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001524 if (wb.mBaseLayer < maxLayer &&
1525 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001526 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001527 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001528 // This window is not related to the previous one in any
1529 // interesting way, so stop here.
1530 break;
1531 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001532 foundW = wb;
1533 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001534 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001535 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001536 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001537 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001538
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001539 if (foundW == null && topCurW != null) {
1540 // There is no wallpaper target, so it goes at the bottom.
1541 // We will assume it is the same place as last time, if known.
1542 foundW = topCurW;
1543 foundI = topCurI+1;
1544 } else {
1545 // Okay i is the position immediately above the wallpaper. Look at
1546 // what is below it for later.
1547 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1548 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001549
Dianne Hackborn284ac932009-08-28 10:34:25 -07001550 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001551 if (mWallpaperTarget.mWallpaperX >= 0) {
1552 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001553 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001554 }
1555 if (mWallpaperTarget.mWallpaperY >= 0) {
1556 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001557 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001558 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001559 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001560
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001561 // Start stepping backwards from here, ensuring that our wallpaper windows
1562 // are correctly placed.
1563 int curTokenIndex = mWallpaperTokens.size();
1564 while (curTokenIndex > 0) {
1565 curTokenIndex--;
1566 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001567 if (token.hidden == visible) {
1568 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1569 token.hidden = !visible;
1570 // Need to do a layout to ensure the wallpaper now has the
1571 // correct size.
1572 mLayoutNeeded = true;
1573 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001574
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001575 int curWallpaperIndex = token.windows.size();
1576 while (curWallpaperIndex > 0) {
1577 curWallpaperIndex--;
1578 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001579
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001580 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001581 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001582 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001583
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001584 // First, make sure the client has the current visibility
1585 // state.
1586 if (wallpaper.mWallpaperVisible != visible) {
1587 wallpaper.mWallpaperVisible = visible;
1588 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001589 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001590 "Setting visibility of wallpaper " + wallpaper
1591 + ": " + visible);
1592 wallpaper.mClient.dispatchAppVisibility(visible);
1593 } catch (RemoteException e) {
1594 }
1595 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001596
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001597 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001598 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001599 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001600
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001601 // First, if this window is at the current index, then all
1602 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001603 if (wallpaper == foundW) {
1604 foundI--;
1605 foundW = foundI > 0
1606 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001607 continue;
1608 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001609
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001610 // The window didn't match... the current wallpaper window,
1611 // wherever it is, is in the wrong place, so make sure it is
1612 // not in the list.
1613 int oldIndex = localmWindows.indexOf(wallpaper);
1614 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001615 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001616 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001617 localmWindows.remove(oldIndex);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001618 if (oldIndex < foundI) {
1619 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001620 }
1621 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001622
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001623 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001624 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001625 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001626 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001627
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001628 localmWindows.add(foundI, wallpaper);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001629 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001630 }
1631 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001632
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001633 return changed;
1634 }
1635
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001636 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001637 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001638 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001639 mWallpaperAnimLayerAdjustment = adj;
1640 int curTokenIndex = mWallpaperTokens.size();
1641 while (curTokenIndex > 0) {
1642 curTokenIndex--;
1643 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1644 int curWallpaperIndex = token.windows.size();
1645 while (curWallpaperIndex > 0) {
1646 curWallpaperIndex--;
1647 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1648 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001649 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001650 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001651 }
1652 }
1653 }
1654
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001655 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1656 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001657 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001658 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001659 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001660 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001661 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1662 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1663 changed = wallpaperWin.mXOffset != offset;
1664 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001666 + wallpaperWin + " x: " + offset);
1667 wallpaperWin.mXOffset = offset;
1668 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001669 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001670 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001671 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001672 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001673 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001674
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001675 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001676 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001677 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1678 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1679 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001680 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001681 + wallpaperWin + " y: " + offset);
1682 changed = true;
1683 wallpaperWin.mYOffset = offset;
1684 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001685 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001686 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001687 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001688 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001689 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001690
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001691 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001692 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001693 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001694 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1695 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001696 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001697 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001698 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001699 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001700 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1701 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001702 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001703 if (mWaitingOnWallpaper != null) {
1704 long start = SystemClock.uptimeMillis();
1705 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1706 < start) {
1707 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001708 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001709 "Waiting for offset complete...");
1710 mWindowMap.wait(WALLPAPER_TIMEOUT);
1711 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001712 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001713 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001714 if ((start+WALLPAPER_TIMEOUT)
1715 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001716 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001717 + wallpaperWin);
1718 mLastWallpaperTimeoutTime = start;
1719 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001720 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001721 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001722 }
1723 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001724 } catch (RemoteException e) {
1725 }
1726 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001727
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001728 return changed;
1729 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001730
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001731 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001732 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001733 if (mWaitingOnWallpaper != null &&
1734 mWaitingOnWallpaper.mClient.asBinder() == window) {
1735 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001736 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001737 }
1738 }
1739 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001740
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001741 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001742 final int dw = mDisplay.getWidth();
1743 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001744
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001745 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001746
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001747 WindowState target = mWallpaperTarget;
1748 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001749 if (target.mWallpaperX >= 0) {
1750 mLastWallpaperX = target.mWallpaperX;
1751 } else if (changingTarget.mWallpaperX >= 0) {
1752 mLastWallpaperX = changingTarget.mWallpaperX;
1753 }
1754 if (target.mWallpaperY >= 0) {
1755 mLastWallpaperY = target.mWallpaperY;
1756 } else if (changingTarget.mWallpaperY >= 0) {
1757 mLastWallpaperY = changingTarget.mWallpaperY;
1758 }
1759 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001760
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001761 int curTokenIndex = mWallpaperTokens.size();
1762 while (curTokenIndex > 0) {
1763 curTokenIndex--;
1764 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1765 int curWallpaperIndex = token.windows.size();
1766 while (curWallpaperIndex > 0) {
1767 curWallpaperIndex--;
1768 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1769 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1770 wallpaper.computeShownFrameLocked();
1771 changed = true;
1772 // We only want to be synchronous with one wallpaper.
1773 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001774 }
1775 }
1776 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001777
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001778 return changed;
1779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001781 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001782 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001783 final int dw = mDisplay.getWidth();
1784 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001785
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001786 int curTokenIndex = mWallpaperTokens.size();
1787 while (curTokenIndex > 0) {
1788 curTokenIndex--;
1789 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001790 if (token.hidden == visible) {
1791 token.hidden = !visible;
1792 // Need to do a layout to ensure the wallpaper now has the
1793 // correct size.
1794 mLayoutNeeded = true;
1795 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001796
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001797 int curWallpaperIndex = token.windows.size();
1798 while (curWallpaperIndex > 0) {
1799 curWallpaperIndex--;
1800 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1801 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001802 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001803 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001804
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001805 if (wallpaper.mWallpaperVisible != visible) {
1806 wallpaper.mWallpaperVisible = visible;
1807 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001808 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001809 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001810 + ": " + visible);
1811 wallpaper.mClient.dispatchAppVisibility(visible);
1812 } catch (RemoteException e) {
1813 }
1814 }
1815 }
1816 }
1817 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001818
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001819 void sendPointerToWallpaperLocked(WindowState srcWin,
1820 MotionEvent pointer, long eventTime) {
1821 int curTokenIndex = mWallpaperTokens.size();
1822 while (curTokenIndex > 0) {
1823 curTokenIndex--;
1824 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1825 int curWallpaperIndex = token.windows.size();
1826 while (curWallpaperIndex > 0) {
1827 curWallpaperIndex--;
1828 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1829 if ((wallpaper.mAttrs.flags &
1830 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
1831 continue;
1832 }
1833 try {
1834 MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
Dianne Hackborn6adba242009-11-10 11:10:09 -08001835 if (srcWin != null) {
1836 ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
1837 srcWin.mFrame.top-wallpaper.mFrame.top);
1838 } else {
1839 ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
1840 }
1841 switch (pointer.getAction()) {
1842 case MotionEvent.ACTION_DOWN:
1843 mSendingPointersToWallpaper = true;
1844 break;
1845 case MotionEvent.ACTION_UP:
1846 mSendingPointersToWallpaper = false;
1847 break;
1848 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001849 wallpaper.mClient.dispatchPointer(ev, eventTime, false);
1850 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001851 Slog.w(TAG, "Failure sending pointer to wallpaper", e);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001852 }
1853 }
1854 }
1855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001856
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001857 void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
1858 MotionEvent pointer, long eventTime, boolean skipped) {
1859 if (relWin != null) {
1860 mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
1861 } else {
1862 mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
1863 }
1864
1865 // If we sent an initial down to the wallpaper, then continue
1866 // sending events until the final up.
1867 if (mSendingPointersToWallpaper) {
1868 if (skipped) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001869 Slog.i(TAG, "Sending skipped pointer to wallpaper!");
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001870 }
1871 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1872
1873 // If we are on top of the wallpaper, then the wallpaper also
1874 // gets to see this movement.
1875 } else if (srcWin != null
1876 && pointer.getAction() == MotionEvent.ACTION_DOWN
1877 && mWallpaperTarget == srcWin
1878 && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
1879 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1880 }
1881 }
1882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 public int addWindow(Session session, IWindow client,
1884 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001885 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 int res = mPolicy.checkAddPermission(attrs);
1887 if (res != WindowManagerImpl.ADD_OKAY) {
1888 return res;
1889 }
Romain Guy06882f82009-06-10 13:36:04 -07001890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 boolean reportNewConfig = false;
1892 WindowState attachedWindow = null;
1893 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 synchronized(mWindowMap) {
1896 // Instantiating a Display requires talking with the simulator,
1897 // so don't do it until we know the system is mostly up and
1898 // running.
1899 if (mDisplay == null) {
1900 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1901 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001902 mInitialDisplayWidth = mDisplay.getWidth();
1903 mInitialDisplayHeight = mDisplay.getHeight();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001904 if (ENABLE_NATIVE_INPUT_DISPATCH) {
1905 mInputManager.setDisplaySize(0,
1906 mInitialDisplayWidth, mInitialDisplayHeight);
1907 } else {
1908 mQueue.setDisplay(mDisplay);
1909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 reportNewConfig = true;
1911 }
Romain Guy06882f82009-06-10 13:36:04 -07001912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001914 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1916 }
1917
1918 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001919 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001921 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001922 + attrs.token + ". Aborting.");
1923 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1924 }
1925 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1926 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001927 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 + attrs.token + ". Aborting.");
1929 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1930 }
1931 }
1932
1933 boolean addToken = false;
1934 WindowToken token = mTokenMap.get(attrs.token);
1935 if (token == null) {
1936 if (attrs.type >= FIRST_APPLICATION_WINDOW
1937 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001938 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001939 + attrs.token + ". Aborting.");
1940 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1941 }
1942 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001943 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 + attrs.token + ". Aborting.");
1945 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1946 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001947 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001948 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001949 + attrs.token + ". Aborting.");
1950 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 token = new WindowToken(attrs.token, -1, false);
1953 addToken = true;
1954 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1955 && attrs.type <= LAST_APPLICATION_WINDOW) {
1956 AppWindowToken atoken = token.appWindowToken;
1957 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001958 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 + token + ". Aborting.");
1960 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1961 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001962 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001963 + token + ". Aborting.");
1964 return WindowManagerImpl.ADD_APP_EXITING;
1965 }
1966 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1967 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001968 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1970 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1971 }
1972 } else if (attrs.type == TYPE_INPUT_METHOD) {
1973 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001974 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001975 + attrs.token + ". Aborting.");
1976 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1977 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001978 } else if (attrs.type == TYPE_WALLPAPER) {
1979 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001980 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001981 + attrs.token + ". Aborting.");
1982 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001984 }
1985
1986 win = new WindowState(session, client, token,
1987 attachedWindow, attrs, viewVisibility);
1988 if (win.mDeathRecipient == null) {
1989 // Client has apparently died, so there is no reason to
1990 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001991 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 + " that is dead, aborting.");
1993 return WindowManagerImpl.ADD_APP_EXITING;
1994 }
1995
1996 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 res = mPolicy.prepareAddWindowLw(win, attrs);
1999 if (res != WindowManagerImpl.ADD_OKAY) {
2000 return res;
2001 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002002
2003 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2004 if (outInputChannel != null) {
2005 String name = win.makeInputChannelName();
2006 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2007 win.mInputChannel = inputChannels[0];
2008 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2009
2010 mInputManager.registerInputChannel(win.mInputChannel);
2011 }
2012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013
2014 // From now on, no exceptions or errors allowed!
2015
2016 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002018 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 if (addToken) {
2021 mTokenMap.put(attrs.token, token);
2022 mTokenList.add(token);
2023 }
2024 win.attach();
2025 mWindowMap.put(client.asBinder(), win);
2026
2027 if (attrs.type == TYPE_APPLICATION_STARTING &&
2028 token.appWindowToken != null) {
2029 token.appWindowToken.startingWindow = win;
2030 }
2031
2032 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 if (attrs.type == TYPE_INPUT_METHOD) {
2035 mInputMethodWindow = win;
2036 addInputMethodWindowToListLocked(win);
2037 imMayMove = false;
2038 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2039 mInputMethodDialogs.add(win);
2040 addWindowToListInOrderLocked(win, true);
2041 adjustInputMethodDialogsLocked();
2042 imMayMove = false;
2043 } else {
2044 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002045 if (attrs.type == TYPE_WALLPAPER) {
2046 mLastWallpaperTimeoutTime = 0;
2047 adjustWallpaperWindowsLocked();
2048 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002049 adjustWallpaperWindowsLocked();
2050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 }
Romain Guy06882f82009-06-10 13:36:04 -07002052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002053 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002055 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002057 if (mInTouchMode) {
2058 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2059 }
2060 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2061 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2062 }
Romain Guy06882f82009-06-10 13:36:04 -07002063
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002064 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002065 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002066 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2067 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 imMayMove = false;
2069 }
2070 }
Romain Guy06882f82009-06-10 13:36:04 -07002071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002073 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 }
Romain Guy06882f82009-06-10 13:36:04 -07002075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 assignLayersLocked();
2077 // Don't do layout here, the window must call
2078 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002080 //dump();
2081
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002082 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002083 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002084 }
Jeff Brown349703e2010-06-22 01:27:15 -07002085
Joe Onorato8a9b2202010-02-26 18:56:32 -08002086 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 TAG, "New client " + client.asBinder()
2088 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002089
2090 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2091 reportNewConfig = true;
2092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094
2095 // sendNewConfiguration() checks caller permissions so we must call it with
2096 // privilege. updateOrientationFromAppTokens() clears and resets the caller
2097 // identity anyway, so it's safe to just clear & restore around this whole
2098 // block.
2099 final long origId = Binder.clearCallingIdentity();
2100 if (reportNewConfig) {
2101 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 }
2103 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 return res;
2106 }
Romain Guy06882f82009-06-10 13:36:04 -07002107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 public void removeWindow(Session session, IWindow client) {
2109 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002110 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002111 if (win == null) {
2112 return;
2113 }
2114 removeWindowLocked(session, win);
2115 }
2116 }
Romain Guy06882f82009-06-10 13:36:04 -07002117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 public void removeWindowLocked(Session session, WindowState win) {
2119
Joe Onorato8a9b2202010-02-26 18:56:32 -08002120 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002121 TAG, "Remove " + win + " client="
2122 + Integer.toHexString(System.identityHashCode(
2123 win.mClient.asBinder()))
2124 + ", surface=" + win.mSurface);
2125
2126 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002127
Joe Onorato8a9b2202010-02-26 18:56:32 -08002128 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2130 + " mExiting=" + win.mExiting
2131 + " isAnimating=" + win.isAnimating()
2132 + " app-animation="
2133 + (win.mAppToken != null ? win.mAppToken.animation : null)
2134 + " inPendingTransaction="
2135 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2136 + " mDisplayFrozen=" + mDisplayFrozen);
2137 // Visibility of the removed window. Will be used later to update orientation later on.
2138 boolean wasVisible = false;
2139 // First, see if we need to run an animation. If we do, we have
2140 // to hold off on removing the window until the animation is done.
2141 // If the display is frozen, just remove immediately, since the
2142 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002143 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 // If we are not currently running the exit animation, we
2145 // need to see about starting one.
2146 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2149 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2150 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2151 }
2152 // Try starting an animation.
2153 if (applyAnimationLocked(win, transit, false)) {
2154 win.mExiting = true;
2155 }
2156 }
2157 if (win.mExiting || win.isAnimating()) {
2158 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002159 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 win.mExiting = true;
2161 win.mRemoveOnExit = true;
2162 mLayoutNeeded = true;
2163 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2164 performLayoutAndPlaceSurfacesLocked();
2165 if (win.mAppToken != null) {
2166 win.mAppToken.updateReportedVisibilityLocked();
2167 }
2168 //dump();
2169 Binder.restoreCallingIdentity(origId);
2170 return;
2171 }
2172 }
2173
2174 removeWindowInnerLocked(session, win);
2175 // Removing a visible window will effect the computed orientation
2176 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002177 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002178 != mForcedAppOrientation
2179 && updateOrientationFromAppTokensLocked()) {
2180 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 }
2182 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2183 Binder.restoreCallingIdentity(origId);
2184 }
Romain Guy06882f82009-06-10 13:36:04 -07002185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 private void removeWindowInnerLocked(Session session, WindowState win) {
Jeff Brown349703e2010-06-22 01:27:15 -07002187 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2188 mInputMonitor.windowIsBeingRemovedLw(win);
2189 } else {
2190 mKeyWaiter.finishedKey(session, win.mClient, true,
2191 KeyWaiter.RETURN_NOTHING);
2192 mKeyWaiter.releasePendingPointerLocked(win.mSession);
2193 mKeyWaiter.releasePendingTrackballLocked(win.mSession);
2194 }
Romain Guy06882f82009-06-10 13:36:04 -07002195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 if (mInputMethodTarget == win) {
2199 moveInputMethodWindowsIfNeededLocked(false);
2200 }
Romain Guy06882f82009-06-10 13:36:04 -07002201
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002202 if (false) {
2203 RuntimeException e = new RuntimeException("here");
2204 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002205 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002206 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002208 mPolicy.removeWindowLw(win);
2209 win.removeLocked();
2210
2211 mWindowMap.remove(win.mClient.asBinder());
2212 mWindows.remove(win);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002213 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214
2215 if (mInputMethodWindow == win) {
2216 mInputMethodWindow = null;
2217 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2218 mInputMethodDialogs.remove(win);
2219 }
Romain Guy06882f82009-06-10 13:36:04 -07002220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 final WindowToken token = win.mToken;
2222 final AppWindowToken atoken = win.mAppToken;
2223 token.windows.remove(win);
2224 if (atoken != null) {
2225 atoken.allAppWindows.remove(win);
2226 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002227 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 TAG, "**** Removing window " + win + ": count="
2229 + token.windows.size());
2230 if (token.windows.size() == 0) {
2231 if (!token.explicit) {
2232 mTokenMap.remove(token.token);
2233 mTokenList.remove(token);
2234 } else if (atoken != null) {
2235 atoken.firstWindowDrawn = false;
2236 }
2237 }
2238
2239 if (atoken != null) {
2240 if (atoken.startingWindow == win) {
2241 atoken.startingWindow = null;
2242 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2243 // If this is the last window and we had requested a starting
2244 // transition window, well there is no point now.
2245 atoken.startingData = null;
2246 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2247 // If this is the last window except for a starting transition
2248 // window, we need to get rid of the starting transition.
2249 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002250 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002251 + ": no more real windows");
2252 }
2253 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2254 mH.sendMessage(m);
2255 }
2256 }
Romain Guy06882f82009-06-10 13:36:04 -07002257
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002258 if (win.mAttrs.type == TYPE_WALLPAPER) {
2259 mLastWallpaperTimeoutTime = 0;
2260 adjustWallpaperWindowsLocked();
2261 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002262 adjustWallpaperWindowsLocked();
2263 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265 if (!mInLayout) {
2266 assignLayersLocked();
2267 mLayoutNeeded = true;
2268 performLayoutAndPlaceSurfacesLocked();
2269 if (win.mAppToken != null) {
2270 win.mAppToken.updateReportedVisibilityLocked();
2271 }
2272 }
2273 }
2274
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002275 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2276 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2277 + ": " + msg + " / " + w.mAttrs.getTitle();
2278 if (where != null) {
2279 Slog.i(TAG, str, where);
2280 } else {
2281 Slog.i(TAG, str);
2282 }
2283 }
2284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2286 long origId = Binder.clearCallingIdentity();
2287 try {
2288 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002289 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002291 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 Surface.openTransaction();
2293 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002294 if (SHOW_TRANSACTIONS) logSurface(w,
2295 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 w.mSurface.setTransparentRegionHint(region);
2297 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002298 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 Surface.closeTransaction();
2300 }
2301 }
2302 }
2303 } finally {
2304 Binder.restoreCallingIdentity(origId);
2305 }
2306 }
2307
2308 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002309 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 Rect visibleInsets) {
2311 long origId = Binder.clearCallingIdentity();
2312 try {
2313 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002314 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 if (w != null) {
2316 w.mGivenInsetsPending = false;
2317 w.mGivenContentInsets.set(contentInsets);
2318 w.mGivenVisibleInsets.set(visibleInsets);
2319 w.mTouchableInsets = touchableInsets;
2320 mLayoutNeeded = true;
2321 performLayoutAndPlaceSurfacesLocked();
2322 }
2323 }
2324 } finally {
2325 Binder.restoreCallingIdentity(origId);
2326 }
2327 }
Romain Guy06882f82009-06-10 13:36:04 -07002328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 public void getWindowDisplayFrame(Session session, IWindow client,
2330 Rect outDisplayFrame) {
2331 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002332 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 if (win == null) {
2334 outDisplayFrame.setEmpty();
2335 return;
2336 }
2337 outDisplayFrame.set(win.mDisplayFrame);
2338 }
2339 }
2340
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002341 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2342 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002343 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2344 window.mWallpaperX = x;
2345 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002346 window.mWallpaperXStep = xStep;
2347 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002348 if (updateWallpaperOffsetLocked(window, true)) {
2349 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002350 }
2351 }
2352 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002353
Dianne Hackborn75804932009-10-20 20:15:20 -07002354 void wallpaperCommandComplete(IBinder window, Bundle result) {
2355 synchronized (mWindowMap) {
2356 if (mWaitingOnWallpaper != null &&
2357 mWaitingOnWallpaper.mClient.asBinder() == window) {
2358 mWaitingOnWallpaper = null;
2359 mWindowMap.notifyAll();
2360 }
2361 }
2362 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002363
Dianne Hackborn75804932009-10-20 20:15:20 -07002364 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2365 String action, int x, int y, int z, Bundle extras, boolean sync) {
2366 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2367 || window == mUpperWallpaperTarget) {
2368 boolean doWait = sync;
2369 int curTokenIndex = mWallpaperTokens.size();
2370 while (curTokenIndex > 0) {
2371 curTokenIndex--;
2372 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2373 int curWallpaperIndex = token.windows.size();
2374 while (curWallpaperIndex > 0) {
2375 curWallpaperIndex--;
2376 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2377 try {
2378 wallpaper.mClient.dispatchWallpaperCommand(action,
2379 x, y, z, extras, sync);
2380 // We only want to be synchronous with one wallpaper.
2381 sync = false;
2382 } catch (RemoteException e) {
2383 }
2384 }
2385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002386
Dianne Hackborn75804932009-10-20 20:15:20 -07002387 if (doWait) {
2388 // XXX Need to wait for result.
2389 }
2390 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002391
Dianne Hackborn75804932009-10-20 20:15:20 -07002392 return null;
2393 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 public int relayoutWindow(Session session, IWindow client,
2396 WindowManager.LayoutParams attrs, int requestedWidth,
2397 int requestedHeight, int viewVisibility, boolean insetsPending,
2398 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002399 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 boolean displayed = false;
2401 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002402 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002406 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 if (win == null) {
2408 return 0;
2409 }
2410 win.mRequestedWidth = requestedWidth;
2411 win.mRequestedHeight = requestedHeight;
2412
2413 if (attrs != null) {
2414 mPolicy.adjustWindowParamsLw(attrs);
2415 }
Romain Guy06882f82009-06-10 13:36:04 -07002416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 int attrChanges = 0;
2418 int flagChanges = 0;
2419 if (attrs != null) {
2420 flagChanges = win.mAttrs.flags ^= attrs.flags;
2421 attrChanges = win.mAttrs.copyFrom(attrs);
2422 }
2423
Joe Onorato8a9b2202010-02-26 18:56:32 -08002424 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425
2426 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2427 win.mAlpha = attrs.alpha;
2428 }
2429
2430 final boolean scaledWindow =
2431 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2432
2433 if (scaledWindow) {
2434 // requested{Width|Height} Surface's physical size
2435 // attrs.{width|height} Size on screen
2436 win.mHScale = (attrs.width != requestedWidth) ?
2437 (attrs.width / (float)requestedWidth) : 1.0f;
2438 win.mVScale = (attrs.height != requestedHeight) ?
2439 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002440 } else {
2441 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
2443
2444 boolean imMayMove = (flagChanges&(
2445 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2446 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 boolean focusMayChange = win.mViewVisibility != viewVisibility
2449 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2450 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002451
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002452 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2453 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 win.mRelayoutCalled = true;
2456 final int oldVisibility = win.mViewVisibility;
2457 win.mViewVisibility = viewVisibility;
2458 if (viewVisibility == View.VISIBLE &&
2459 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2460 displayed = !win.isVisibleLw();
2461 if (win.mExiting) {
2462 win.mExiting = false;
2463 win.mAnimation = null;
2464 }
2465 if (win.mDestroying) {
2466 win.mDestroying = false;
2467 mDestroySurface.remove(win);
2468 }
2469 if (oldVisibility == View.GONE) {
2470 win.mEnterAnimationPending = true;
2471 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002472 if (displayed) {
2473 if (win.mSurface != null && !win.mDrawPending
2474 && !win.mCommitDrawPending && !mDisplayFrozen
2475 && mPolicy.isScreenOn()) {
2476 applyEnterAnimationLocked(win);
2477 }
2478 if ((win.mAttrs.flags
2479 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2480 if (DEBUG_VISIBILITY) Slog.v(TAG,
2481 "Relayout window turning screen on: " + win);
2482 win.mTurnOnScreen = true;
2483 }
2484 int diff = 0;
2485 if (win.mConfiguration != mCurConfiguration
2486 && (win.mConfiguration == null
2487 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2488 win.mConfiguration = mCurConfiguration;
2489 if (DEBUG_CONFIGURATION) {
2490 Slog.i(TAG, "Window " + win + " visible with new config: "
2491 + win.mConfiguration + " / 0x"
2492 + Integer.toHexString(diff));
2493 }
2494 outConfig.setTo(mCurConfiguration);
2495 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2498 // To change the format, we need to re-build the surface.
2499 win.destroySurfaceLocked();
2500 displayed = true;
2501 }
2502 try {
2503 Surface surface = win.createSurfaceLocked();
2504 if (surface != null) {
2505 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002506 win.mReportDestroySurface = false;
2507 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002508 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002509 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002511 // For some reason there isn't a surface. Clear the
2512 // caller's object so they see the same state.
2513 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 }
2515 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002516 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002517 + client + " (" + win.mAttrs.getTitle() + ")",
2518 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 Binder.restoreCallingIdentity(origId);
2520 return 0;
2521 }
2522 if (displayed) {
2523 focusMayChange = true;
2524 }
2525 if (win.mAttrs.type == TYPE_INPUT_METHOD
2526 && mInputMethodWindow == null) {
2527 mInputMethodWindow = win;
2528 imMayMove = true;
2529 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002530 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2531 && win.mAppToken != null
2532 && win.mAppToken.startingWindow != null) {
2533 // Special handling of starting window over the base
2534 // window of the app: propagate lock screen flags to it,
2535 // to provide the correct semantics while starting.
2536 final int mask =
2537 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002538 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2539 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002540 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2541 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543 } else {
2544 win.mEnterAnimationPending = false;
2545 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002546 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002547 + ": mExiting=" + win.mExiting
2548 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 // If we are not currently running the exit animation, we
2550 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002551 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 // Try starting an animation; if there isn't one, we
2553 // can destroy the surface right away.
2554 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2555 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2556 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2557 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002558 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002560 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 win.mExiting = true;
Jeff Brown349703e2010-06-22 01:27:15 -07002562 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2563 mInputMonitor.windowIsBecomingInvisibleLw(win);
2564 } else {
2565 mKeyWaiter.finishedKey(session, client, true,
2566 KeyWaiter.RETURN_NOTHING);
2567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 } else if (win.isAnimating()) {
2569 // Currently in a hide animation... turn this into
2570 // an exit.
2571 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002572 } else if (win == mWallpaperTarget) {
2573 // If the wallpaper is currently behind this
2574 // window, we need to change both of them inside
2575 // of a transaction to avoid artifacts.
2576 win.mExiting = true;
2577 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 } else {
2579 if (mInputMethodWindow == win) {
2580 mInputMethodWindow = null;
2581 }
2582 win.destroySurfaceLocked();
2583 }
2584 }
2585 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002586
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002587 if (win.mSurface == null || (win.getAttrs().flags
2588 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2589 || win.mSurfacePendingDestroy) {
2590 // We are being called from a local process, which
2591 // means outSurface holds its current surface. Ensure the
2592 // surface object is cleared, but we don't want it actually
2593 // destroyed at this point.
2594 win.mSurfacePendingDestroy = false;
2595 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002596 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002597 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002598 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002599 "Keeping surface, will report destroy: " + win);
2600 win.mReportDestroySurface = true;
2601 outSurface.copyFrom(win.mSurface);
2602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 }
2604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 if (focusMayChange) {
2606 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2607 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 imMayMove = false;
2609 }
2610 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2611 }
Romain Guy06882f82009-06-10 13:36:04 -07002612
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002613 // updateFocusedWindowLocked() already assigned layers so we only need to
2614 // reassign them at this point if the IM window state gets shuffled
2615 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002618 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2619 // Little hack here -- we -should- be able to rely on the
2620 // function to return true if the IME has moved and needs
2621 // its layer recomputed. However, if the IME was hidden
2622 // and isn't actually moved in the list, its layer may be
2623 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 assignLayers = true;
2625 }
2626 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002627 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002628 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002629 assignLayers = true;
2630 }
2631 }
Romain Guy06882f82009-06-10 13:36:04 -07002632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 mLayoutNeeded = true;
2634 win.mGivenInsetsPending = insetsPending;
2635 if (assignLayers) {
2636 assignLayersLocked();
2637 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002638 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002640 if (displayed && win.mIsWallpaper) {
2641 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002642 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 if (win.mAppToken != null) {
2645 win.mAppToken.updateReportedVisibilityLocked();
2646 }
2647 outFrame.set(win.mFrame);
2648 outContentInsets.set(win.mContentInsets);
2649 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002650 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002652 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 + ", requestedHeight=" + requestedHeight
2654 + ", viewVisibility=" + viewVisibility
2655 + "\nRelayout returning frame=" + outFrame
2656 + ", surface=" + outSurface);
2657
Joe Onorato8a9b2202010-02-26 18:56:32 -08002658 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2660
2661 inTouchMode = mInTouchMode;
2662 }
2663
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002664 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 sendNewConfiguration();
2666 }
Romain Guy06882f82009-06-10 13:36:04 -07002667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2671 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2672 }
2673
2674 public void finishDrawingWindow(Session session, IWindow client) {
2675 final long origId = Binder.clearCallingIdentity();
2676 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002677 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002679 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2680 adjustWallpaperWindowsLocked();
2681 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 mLayoutNeeded = true;
2683 performLayoutAndPlaceSurfacesLocked();
2684 }
2685 }
2686 Binder.restoreCallingIdentity(origId);
2687 }
2688
2689 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002690 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 + (lp != null ? lp.packageName : null)
2692 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2693 if (lp != null && lp.windowAnimations != 0) {
2694 // If this is a system resource, don't try to load it from the
2695 // application resources. It is nice to avoid loading application
2696 // resources if we can.
2697 String packageName = lp.packageName != null ? lp.packageName : "android";
2698 int resId = lp.windowAnimations;
2699 if ((resId&0xFF000000) == 0x01000000) {
2700 packageName = "android";
2701 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002702 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 + packageName);
2704 return AttributeCache.instance().get(packageName, resId,
2705 com.android.internal.R.styleable.WindowAnimation);
2706 }
2707 return null;
2708 }
Romain Guy06882f82009-06-10 13:36:04 -07002709
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002710 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002711 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002712 + packageName + " resId=0x" + Integer.toHexString(resId));
2713 if (packageName != null) {
2714 if ((resId&0xFF000000) == 0x01000000) {
2715 packageName = "android";
2716 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002717 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002718 + packageName);
2719 return AttributeCache.instance().get(packageName, resId,
2720 com.android.internal.R.styleable.WindowAnimation);
2721 }
2722 return null;
2723 }
2724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 private void applyEnterAnimationLocked(WindowState win) {
2726 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2727 if (win.mEnterAnimationPending) {
2728 win.mEnterAnimationPending = false;
2729 transit = WindowManagerPolicy.TRANSIT_ENTER;
2730 }
2731
2732 applyAnimationLocked(win, transit, true);
2733 }
2734
2735 private boolean applyAnimationLocked(WindowState win,
2736 int transit, boolean isEntrance) {
2737 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2738 // If we are trying to apply an animation, but already running
2739 // an animation of the same type, then just leave that one alone.
2740 return true;
2741 }
Romain Guy06882f82009-06-10 13:36:04 -07002742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 // Only apply an animation if the display isn't frozen. If it is
2744 // frozen, there is no reason to animate and it can cause strange
2745 // artifacts when we unfreeze the display if some different animation
2746 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002747 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 int anim = mPolicy.selectAnimationLw(win, transit);
2749 int attr = -1;
2750 Animation a = null;
2751 if (anim != 0) {
2752 a = AnimationUtils.loadAnimation(mContext, anim);
2753 } else {
2754 switch (transit) {
2755 case WindowManagerPolicy.TRANSIT_ENTER:
2756 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2757 break;
2758 case WindowManagerPolicy.TRANSIT_EXIT:
2759 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2760 break;
2761 case WindowManagerPolicy.TRANSIT_SHOW:
2762 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2763 break;
2764 case WindowManagerPolicy.TRANSIT_HIDE:
2765 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2766 break;
2767 }
2768 if (attr >= 0) {
2769 a = loadAnimation(win.mAttrs, attr);
2770 }
2771 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002772 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002773 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2774 + " mAnimation=" + win.mAnimation
2775 + " isEntrance=" + isEntrance);
2776 if (a != null) {
2777 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002778 RuntimeException e = null;
2779 if (!HIDE_STACK_CRAWLS) {
2780 e = new RuntimeException();
2781 e.fillInStackTrace();
2782 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002783 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 }
2785 win.setAnimation(a);
2786 win.mAnimationIsEntrance = isEntrance;
2787 }
2788 } else {
2789 win.clearAnimation();
2790 }
2791
2792 return win.mAnimation != null;
2793 }
2794
2795 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2796 int anim = 0;
2797 Context context = mContext;
2798 if (animAttr >= 0) {
2799 AttributeCache.Entry ent = getCachedAnimations(lp);
2800 if (ent != null) {
2801 context = ent.context;
2802 anim = ent.array.getResourceId(animAttr, 0);
2803 }
2804 }
2805 if (anim != 0) {
2806 return AnimationUtils.loadAnimation(context, anim);
2807 }
2808 return null;
2809 }
Romain Guy06882f82009-06-10 13:36:04 -07002810
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002811 private Animation loadAnimation(String packageName, int resId) {
2812 int anim = 0;
2813 Context context = mContext;
2814 if (resId >= 0) {
2815 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2816 if (ent != null) {
2817 context = ent.context;
2818 anim = resId;
2819 }
2820 }
2821 if (anim != 0) {
2822 return AnimationUtils.loadAnimation(context, anim);
2823 }
2824 return null;
2825 }
2826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 private boolean applyAnimationLocked(AppWindowToken wtoken,
2828 WindowManager.LayoutParams lp, int transit, boolean enter) {
2829 // Only apply an animation if the display isn't frozen. If it is
2830 // frozen, there is no reason to animate and it can cause strange
2831 // artifacts when we unfreeze the display if some different animation
2832 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002833 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002834 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002835 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002836 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002837 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002838 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002839 } else if (mNextAppTransitionPackage != null) {
2840 a = loadAnimation(mNextAppTransitionPackage, enter ?
2841 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002842 } else {
2843 int animAttr = 0;
2844 switch (transit) {
2845 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2846 animAttr = enter
2847 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2848 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2849 break;
2850 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2851 animAttr = enter
2852 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2853 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2854 break;
2855 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2856 animAttr = enter
2857 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2858 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2859 break;
2860 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2861 animAttr = enter
2862 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2863 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2864 break;
2865 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2866 animAttr = enter
2867 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2868 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2869 break;
2870 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2871 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002872 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002873 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2874 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002875 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002876 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002877 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2878 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002879 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002880 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002881 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002882 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2883 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2884 break;
2885 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2886 animAttr = enter
2887 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2888 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2889 break;
2890 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2891 animAttr = enter
2892 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2893 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002894 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002895 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002896 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002897 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002898 + " anim=" + a
2899 + " animAttr=0x" + Integer.toHexString(animAttr)
2900 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002902 if (a != null) {
2903 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002904 RuntimeException e = null;
2905 if (!HIDE_STACK_CRAWLS) {
2906 e = new RuntimeException();
2907 e.fillInStackTrace();
2908 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002909 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 }
2911 wtoken.setAnimation(a);
2912 }
2913 } else {
2914 wtoken.clearAnimation();
2915 }
2916
2917 return wtoken.animation != null;
2918 }
2919
2920 // -------------------------------------------------------------
2921 // Application Window Tokens
2922 // -------------------------------------------------------------
2923
2924 public void validateAppTokens(List tokens) {
2925 int v = tokens.size()-1;
2926 int m = mAppTokens.size()-1;
2927 while (v >= 0 && m >= 0) {
2928 AppWindowToken wtoken = mAppTokens.get(m);
2929 if (wtoken.removed) {
2930 m--;
2931 continue;
2932 }
2933 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002934 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2936 }
2937 v--;
2938 m--;
2939 }
2940 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002941 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 v--;
2943 }
2944 while (m >= 0) {
2945 AppWindowToken wtoken = mAppTokens.get(m);
2946 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002947 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 }
2949 m--;
2950 }
2951 }
2952
2953 boolean checkCallingPermission(String permission, String func) {
2954 // Quick check: if the calling permission is me, it's all okay.
2955 if (Binder.getCallingPid() == Process.myPid()) {
2956 return true;
2957 }
Romain Guy06882f82009-06-10 13:36:04 -07002958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 if (mContext.checkCallingPermission(permission)
2960 == PackageManager.PERMISSION_GRANTED) {
2961 return true;
2962 }
2963 String msg = "Permission Denial: " + func + " from pid="
2964 + Binder.getCallingPid()
2965 + ", uid=" + Binder.getCallingUid()
2966 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002967 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002968 return false;
2969 }
Romain Guy06882f82009-06-10 13:36:04 -07002970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 AppWindowToken findAppWindowToken(IBinder token) {
2972 WindowToken wtoken = mTokenMap.get(token);
2973 if (wtoken == null) {
2974 return null;
2975 }
2976 return wtoken.appWindowToken;
2977 }
Romain Guy06882f82009-06-10 13:36:04 -07002978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 public void addWindowToken(IBinder token, int type) {
2980 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2981 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002982 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 }
Romain Guy06882f82009-06-10 13:36:04 -07002984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 synchronized(mWindowMap) {
2986 WindowToken wtoken = mTokenMap.get(token);
2987 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002988 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 return;
2990 }
2991 wtoken = new WindowToken(token, type, true);
2992 mTokenMap.put(token, wtoken);
2993 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002994 if (type == TYPE_WALLPAPER) {
2995 mWallpaperTokens.add(wtoken);
2996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002997 }
2998 }
Romain Guy06882f82009-06-10 13:36:04 -07002999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003000 public void removeWindowToken(IBinder token) {
3001 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3002 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003003 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 }
3005
3006 final long origId = Binder.clearCallingIdentity();
3007 synchronized(mWindowMap) {
3008 WindowToken wtoken = mTokenMap.remove(token);
3009 mTokenList.remove(wtoken);
3010 if (wtoken != null) {
3011 boolean delayed = false;
3012 if (!wtoken.hidden) {
3013 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015 final int N = wtoken.windows.size();
3016 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 for (int i=0; i<N; i++) {
3019 WindowState win = wtoken.windows.get(i);
3020
3021 if (win.isAnimating()) {
3022 delayed = true;
3023 }
Romain Guy06882f82009-06-10 13:36:04 -07003024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 if (win.isVisibleNow()) {
3026 applyAnimationLocked(win,
3027 WindowManagerPolicy.TRANSIT_EXIT, false);
Jeff Brown349703e2010-06-22 01:27:15 -07003028 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3029 mInputMonitor.windowIsBeingRemovedLw(win);
3030 } else {
3031 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3032 KeyWaiter.RETURN_NOTHING);
3033 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003034 changed = true;
3035 }
3036 }
3037
3038 if (changed) {
3039 mLayoutNeeded = true;
3040 performLayoutAndPlaceSurfacesLocked();
3041 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3042 }
Romain Guy06882f82009-06-10 13:36:04 -07003043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044 if (delayed) {
3045 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003046 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3047 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 }
3049 }
Romain Guy06882f82009-06-10 13:36:04 -07003050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003052 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
3054 }
3055 Binder.restoreCallingIdentity(origId);
3056 }
3057
3058 public void addAppToken(int addPos, IApplicationToken token,
3059 int groupId, int requestedOrientation, boolean fullscreen) {
3060 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3061 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003062 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003063 }
Jeff Brown349703e2010-06-22 01:27:15 -07003064
3065 // Get the dispatching timeout here while we are not holding any locks so that it
3066 // can be cached by the AppWindowToken. The timeout value is used later by the
3067 // input dispatcher in code that does hold locks. If we did not cache the value
3068 // here we would run the chance of introducing a deadlock between the window manager
3069 // (which holds locks while updating the input dispatcher state) and the activity manager
3070 // (which holds locks while querying the application token).
3071 long inputDispatchingTimeoutNanos;
3072 try {
3073 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3074 } catch (RemoteException ex) {
3075 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3076 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3077 }
Romain Guy06882f82009-06-10 13:36:04 -07003078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 synchronized(mWindowMap) {
3080 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3081 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003082 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 return;
3084 }
3085 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003086 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 wtoken.groupId = groupId;
3088 wtoken.appFullscreen = fullscreen;
3089 wtoken.requestedOrientation = requestedOrientation;
3090 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003091 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003092 mTokenMap.put(token.asBinder(), wtoken);
3093 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003095 // Application tokens start out hidden.
3096 wtoken.hidden = true;
3097 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 //dump();
3100 }
3101 }
Romain Guy06882f82009-06-10 13:36:04 -07003102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003103 public void setAppGroupId(IBinder token, int groupId) {
3104 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3105 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003106 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003107 }
3108
3109 synchronized(mWindowMap) {
3110 AppWindowToken wtoken = findAppWindowToken(token);
3111 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003112 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 return;
3114 }
3115 wtoken.groupId = groupId;
3116 }
3117 }
Romain Guy06882f82009-06-10 13:36:04 -07003118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 public int getOrientationFromWindowsLocked() {
3120 int pos = mWindows.size() - 1;
3121 while (pos >= 0) {
3122 WindowState wtoken = (WindowState) mWindows.get(pos);
3123 pos--;
3124 if (wtoken.mAppToken != null) {
3125 // We hit an application window. so the orientation will be determined by the
3126 // app window. No point in continuing further.
3127 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3128 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003129 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003130 continue;
3131 }
3132 int req = wtoken.mAttrs.screenOrientation;
3133 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3134 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3135 continue;
3136 } else {
3137 return req;
3138 }
3139 }
3140 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3141 }
Romain Guy06882f82009-06-10 13:36:04 -07003142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003144 int pos = mAppTokens.size() - 1;
3145 int curGroup = 0;
3146 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3147 boolean findingBehind = false;
3148 boolean haveGroup = false;
3149 boolean lastFullscreen = false;
3150 while (pos >= 0) {
3151 AppWindowToken wtoken = mAppTokens.get(pos);
3152 pos--;
3153 // if we're about to tear down this window and not seek for
3154 // the behind activity, don't use it for orientation
3155 if (!findingBehind
3156 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3157 continue;
3158 }
3159
3160 if (!haveGroup) {
3161 // We ignore any hidden applications on the top.
3162 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003163 continue;
3164 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003165 haveGroup = true;
3166 curGroup = wtoken.groupId;
3167 lastOrientation = wtoken.requestedOrientation;
3168 } else if (curGroup != wtoken.groupId) {
3169 // If we have hit a new application group, and the bottom
3170 // of the previous group didn't explicitly say to use
3171 // the orientation behind it, and the last app was
3172 // full screen, then we'll stick with the
3173 // user's orientation.
3174 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3175 && lastFullscreen) {
3176 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003179 int or = wtoken.requestedOrientation;
3180 // If this application is fullscreen, and didn't explicitly say
3181 // to use the orientation behind it, then just take whatever
3182 // orientation it has and ignores whatever is under it.
3183 lastFullscreen = wtoken.appFullscreen;
3184 if (lastFullscreen
3185 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3186 return or;
3187 }
3188 // If this application has requested an explicit orientation,
3189 // then use it.
3190 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3191 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3192 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3193 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3194 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3195 return or;
3196 }
3197 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3198 }
3199 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 }
Romain Guy06882f82009-06-10 13:36:04 -07003201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003202 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003203 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003204 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3205 "updateOrientationFromAppTokens()")) {
3206 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3207 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003208
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003209 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003210 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003211
3212 synchronized(mWindowMap) {
3213 if (updateOrientationFromAppTokensLocked()) {
3214 if (freezeThisOneIfNeeded != null) {
3215 AppWindowToken wtoken = findAppWindowToken(
3216 freezeThisOneIfNeeded);
3217 if (wtoken != null) {
3218 startAppFreezingScreenLocked(wtoken,
3219 ActivityInfo.CONFIG_ORIENTATION);
3220 }
3221 }
3222 config = computeNewConfigurationLocked();
3223
3224 } else if (currentConfig != null) {
3225 // No obvious action we need to take, but if our current
3226 // state mismatches the activity maanager's, update it
3227 mTempConfiguration.setToDefaults();
3228 if (computeNewConfigurationLocked(mTempConfiguration)) {
3229 if (currentConfig.diff(mTempConfiguration) != 0) {
3230 mWaitingForConfig = true;
3231 mLayoutNeeded = true;
3232 startFreezingDisplayLocked();
3233 config = new Configuration(mTempConfiguration);
3234 }
3235 }
3236 }
3237 }
3238
Dianne Hackborncfaef692009-06-15 14:24:44 -07003239 Binder.restoreCallingIdentity(ident);
3240 return config;
3241 }
3242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003243 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003244 * Determine the new desired orientation of the display, returning
3245 * a non-null new Configuration if it has changed from the current
3246 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3247 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3248 * SCREEN. This will typically be done for you if you call
3249 * sendNewConfiguration().
3250 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003251 * The orientation is computed from non-application windows first. If none of
3252 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003253 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3255 * android.os.IBinder)
3256 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003257 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003258 if (mDisplayFrozen) {
3259 // If the display is frozen, some activities may be in the middle
3260 // of restarting, and thus have removed their old window. If the
3261 // window has the flag to hide the lock screen, then the lock screen
3262 // can re-appear and inflict its own orientation on us. Keep the
3263 // orientation stable until this all settles down.
3264 return false;
3265 }
3266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003267 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 long ident = Binder.clearCallingIdentity();
3269 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003270 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 mForcedAppOrientation = req;
3274 //send a message to Policy indicating orientation change to take
3275 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003276 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003277 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3278 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3279 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 }
3281 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003282
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003283 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 } finally {
3285 Binder.restoreCallingIdentity(ident);
3286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003287 }
Romain Guy06882f82009-06-10 13:36:04 -07003288
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003289 int computeForcedAppOrientationLocked() {
3290 int req = getOrientationFromWindowsLocked();
3291 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3292 req = getOrientationFromAppTokensLocked();
3293 }
3294 return req;
3295 }
Romain Guy06882f82009-06-10 13:36:04 -07003296
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003297 public void setNewConfiguration(Configuration config) {
3298 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3299 "setNewConfiguration()")) {
3300 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3301 }
3302
3303 synchronized(mWindowMap) {
3304 mCurConfiguration = new Configuration(config);
3305 mWaitingForConfig = false;
3306 performLayoutAndPlaceSurfacesLocked();
3307 }
3308 }
3309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3311 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3312 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003313 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314 }
Romain Guy06882f82009-06-10 13:36:04 -07003315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 synchronized(mWindowMap) {
3317 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3318 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003319 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 return;
3321 }
Romain Guy06882f82009-06-10 13:36:04 -07003322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 wtoken.requestedOrientation = requestedOrientation;
3324 }
3325 }
Romain Guy06882f82009-06-10 13:36:04 -07003326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 public int getAppOrientation(IApplicationToken token) {
3328 synchronized(mWindowMap) {
3329 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3330 if (wtoken == null) {
3331 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3332 }
Romain Guy06882f82009-06-10 13:36:04 -07003333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 return wtoken.requestedOrientation;
3335 }
3336 }
Romain Guy06882f82009-06-10 13:36:04 -07003337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3339 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3340 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003341 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 }
3343
3344 synchronized(mWindowMap) {
3345 boolean changed = false;
3346 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003347 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 changed = mFocusedApp != null;
3349 mFocusedApp = null;
Jeff Brown349703e2010-06-22 01:27:15 -07003350 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3351 if (changed) {
3352 mInputMonitor.setFocusedAppLw(null);
3353 }
3354 } else {
3355 mKeyWaiter.tickle();
3356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 } else {
3358 AppWindowToken newFocus = findAppWindowToken(token);
3359 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003360 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 return;
3362 }
3363 changed = mFocusedApp != newFocus;
3364 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003365 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown349703e2010-06-22 01:27:15 -07003366 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3367 if (changed) {
3368 mInputMonitor.setFocusedAppLw(newFocus);
3369 }
3370 } else {
3371 mKeyWaiter.tickle();
3372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 }
3374
3375 if (moveFocusNow && changed) {
3376 final long origId = Binder.clearCallingIdentity();
3377 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3378 Binder.restoreCallingIdentity(origId);
3379 }
3380 }
3381 }
3382
3383 public void prepareAppTransition(int transit) {
3384 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3385 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003386 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 }
Romain Guy06882f82009-06-10 13:36:04 -07003388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003390 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003391 TAG, "Prepare app transition: transit=" + transit
3392 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003393 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003394 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3395 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003397 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3398 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3399 // Opening a new task always supersedes a close for the anim.
3400 mNextAppTransition = transit;
3401 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3402 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3403 // Opening a new activity always supersedes a close for the anim.
3404 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 }
3406 mAppTransitionReady = false;
3407 mAppTransitionTimeout = false;
3408 mStartingIconInTransition = false;
3409 mSkipAppTransitionAnimation = false;
3410 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3411 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3412 5000);
3413 }
3414 }
3415 }
3416
3417 public int getPendingAppTransition() {
3418 return mNextAppTransition;
3419 }
Romain Guy06882f82009-06-10 13:36:04 -07003420
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003421 public void overridePendingAppTransition(String packageName,
3422 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003423 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003424 mNextAppTransitionPackage = packageName;
3425 mNextAppTransitionEnter = enterAnim;
3426 mNextAppTransitionExit = exitAnim;
3427 }
3428 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 public void executeAppTransition() {
3431 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3432 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003433 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 }
Romain Guy06882f82009-06-10 13:36:04 -07003435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003436 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003437 if (DEBUG_APP_TRANSITIONS) {
3438 RuntimeException e = new RuntimeException("here");
3439 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003440 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003441 + mNextAppTransition, e);
3442 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003443 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003444 mAppTransitionReady = true;
3445 final long origId = Binder.clearCallingIdentity();
3446 performLayoutAndPlaceSurfacesLocked();
3447 Binder.restoreCallingIdentity(origId);
3448 }
3449 }
3450 }
3451
3452 public void setAppStartingWindow(IBinder token, String pkg,
3453 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3454 IBinder transferFrom, boolean createIfNeeded) {
3455 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3456 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003457 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 }
3459
3460 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003461 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003462 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3463 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 AppWindowToken wtoken = findAppWindowToken(token);
3466 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003467 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003468 return;
3469 }
3470
3471 // If the display is frozen, we won't do anything until the
3472 // actual window is displayed so there is no reason to put in
3473 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003474 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 return;
3476 }
Romain Guy06882f82009-06-10 13:36:04 -07003477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003478 if (wtoken.startingData != null) {
3479 return;
3480 }
Romain Guy06882f82009-06-10 13:36:04 -07003481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 if (transferFrom != null) {
3483 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3484 if (ttoken != null) {
3485 WindowState startingWindow = ttoken.startingWindow;
3486 if (startingWindow != null) {
3487 if (mStartingIconInTransition) {
3488 // In this case, the starting icon has already
3489 // been displayed, so start letting windows get
3490 // shown immediately without any more transitions.
3491 mSkipAppTransitionAnimation = true;
3492 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003493 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 "Moving existing starting from " + ttoken
3495 + " to " + wtoken);
3496 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 // Transfer the starting window over to the new
3499 // token.
3500 wtoken.startingData = ttoken.startingData;
3501 wtoken.startingView = ttoken.startingView;
3502 wtoken.startingWindow = startingWindow;
3503 ttoken.startingData = null;
3504 ttoken.startingView = null;
3505 ttoken.startingWindow = null;
3506 ttoken.startingMoved = true;
3507 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003508 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003510 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003511 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 mWindows.remove(startingWindow);
3513 ttoken.windows.remove(startingWindow);
3514 ttoken.allAppWindows.remove(startingWindow);
3515 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 // Propagate other interesting state between the
3518 // tokens. If the old token is displayed, we should
3519 // immediately force the new one to be displayed. If
3520 // it is animating, we need to move that animation to
3521 // the new one.
3522 if (ttoken.allDrawn) {
3523 wtoken.allDrawn = true;
3524 }
3525 if (ttoken.firstWindowDrawn) {
3526 wtoken.firstWindowDrawn = true;
3527 }
3528 if (!ttoken.hidden) {
3529 wtoken.hidden = false;
3530 wtoken.hiddenRequested = false;
3531 wtoken.willBeHidden = false;
3532 }
3533 if (wtoken.clientHidden != ttoken.clientHidden) {
3534 wtoken.clientHidden = ttoken.clientHidden;
3535 wtoken.sendAppVisibilityToClients();
3536 }
3537 if (ttoken.animation != null) {
3538 wtoken.animation = ttoken.animation;
3539 wtoken.animating = ttoken.animating;
3540 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3541 ttoken.animation = null;
3542 ttoken.animLayerAdjustment = 0;
3543 wtoken.updateLayers();
3544 ttoken.updateLayers();
3545 }
Romain Guy06882f82009-06-10 13:36:04 -07003546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 mLayoutNeeded = true;
3549 performLayoutAndPlaceSurfacesLocked();
3550 Binder.restoreCallingIdentity(origId);
3551 return;
3552 } else if (ttoken.startingData != null) {
3553 // The previous app was getting ready to show a
3554 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003555 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 "Moving pending starting from " + ttoken
3557 + " to " + wtoken);
3558 wtoken.startingData = ttoken.startingData;
3559 ttoken.startingData = null;
3560 ttoken.startingMoved = true;
3561 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3562 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3563 // want to process the message ASAP, before any other queued
3564 // messages.
3565 mH.sendMessageAtFrontOfQueue(m);
3566 return;
3567 }
3568 }
3569 }
3570
3571 // There is no existing starting window, and the caller doesn't
3572 // want us to create one, so that's it!
3573 if (!createIfNeeded) {
3574 return;
3575 }
Romain Guy06882f82009-06-10 13:36:04 -07003576
Dianne Hackborn284ac932009-08-28 10:34:25 -07003577 // If this is a translucent or wallpaper window, then don't
3578 // show a starting window -- the current effect (a full-screen
3579 // opaque starting window that fades away to the real contents
3580 // when it is ready) does not work for this.
3581 if (theme != 0) {
3582 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3583 com.android.internal.R.styleable.Window);
3584 if (ent.array.getBoolean(
3585 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3586 return;
3587 }
3588 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003589 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3590 return;
3591 }
3592 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003593 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3594 return;
3595 }
3596 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 mStartingIconInTransition = true;
3599 wtoken.startingData = new StartingData(
3600 pkg, theme, nonLocalizedLabel,
3601 labelRes, icon);
3602 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3603 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3604 // want to process the message ASAP, before any other queued
3605 // messages.
3606 mH.sendMessageAtFrontOfQueue(m);
3607 }
3608 }
3609
3610 public void setAppWillBeHidden(IBinder token) {
3611 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3612 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003613 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 }
3615
3616 AppWindowToken wtoken;
3617
3618 synchronized(mWindowMap) {
3619 wtoken = findAppWindowToken(token);
3620 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003621 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 -08003622 return;
3623 }
3624 wtoken.willBeHidden = true;
3625 }
3626 }
Romain Guy06882f82009-06-10 13:36:04 -07003627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3629 boolean visible, int transit, boolean performLayout) {
3630 boolean delayed = false;
3631
3632 if (wtoken.clientHidden == visible) {
3633 wtoken.clientHidden = !visible;
3634 wtoken.sendAppVisibilityToClients();
3635 }
Romain Guy06882f82009-06-10 13:36:04 -07003636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637 wtoken.willBeHidden = false;
3638 if (wtoken.hidden == visible) {
3639 final int N = wtoken.allAppWindows.size();
3640 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003641 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3643 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003646
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003647 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003648 if (wtoken.animation == sDummyAnimation) {
3649 wtoken.animation = null;
3650 }
3651 applyAnimationLocked(wtoken, lp, transit, visible);
3652 changed = true;
3653 if (wtoken.animation != null) {
3654 delayed = runningAppAnimation = true;
3655 }
3656 }
Romain Guy06882f82009-06-10 13:36:04 -07003657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 for (int i=0; i<N; i++) {
3659 WindowState win = wtoken.allAppWindows.get(i);
3660 if (win == wtoken.startingWindow) {
3661 continue;
3662 }
3663
3664 if (win.isAnimating()) {
3665 delayed = true;
3666 }
Romain Guy06882f82009-06-10 13:36:04 -07003667
Joe Onorato8a9b2202010-02-26 18:56:32 -08003668 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 //win.dump(" ");
3670 if (visible) {
3671 if (!win.isVisibleNow()) {
3672 if (!runningAppAnimation) {
3673 applyAnimationLocked(win,
3674 WindowManagerPolicy.TRANSIT_ENTER, true);
3675 }
3676 changed = true;
3677 }
3678 } else if (win.isVisibleNow()) {
3679 if (!runningAppAnimation) {
3680 applyAnimationLocked(win,
3681 WindowManagerPolicy.TRANSIT_EXIT, false);
3682 }
Jeff Brown349703e2010-06-22 01:27:15 -07003683 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3684 mInputMonitor.windowIsBecomingInvisibleLw(win);
3685 } else {
3686 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3687 KeyWaiter.RETURN_NOTHING);
3688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003689 changed = true;
3690 }
3691 }
3692
3693 wtoken.hidden = wtoken.hiddenRequested = !visible;
3694 if (!visible) {
3695 unsetAppFreezingScreenLocked(wtoken, true, true);
3696 } else {
3697 // If we are being set visible, and the starting window is
3698 // not yet displayed, then make sure it doesn't get displayed.
3699 WindowState swin = wtoken.startingWindow;
3700 if (swin != null && (swin.mDrawPending
3701 || swin.mCommitDrawPending)) {
3702 swin.mPolicyVisibility = false;
3703 swin.mPolicyVisibilityAfterAnim = false;
3704 }
3705 }
Romain Guy06882f82009-06-10 13:36:04 -07003706
Joe Onorato8a9b2202010-02-26 18:56:32 -08003707 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3709 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003710
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003711 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003713 if (performLayout) {
3714 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3715 performLayoutAndPlaceSurfacesLocked();
3716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 }
3718 }
3719
3720 if (wtoken.animation != null) {
3721 delayed = true;
3722 }
Romain Guy06882f82009-06-10 13:36:04 -07003723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 return delayed;
3725 }
3726
3727 public void setAppVisibility(IBinder token, boolean visible) {
3728 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3729 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003730 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 }
3732
3733 AppWindowToken wtoken;
3734
3735 synchronized(mWindowMap) {
3736 wtoken = findAppWindowToken(token);
3737 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003738 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 return;
3740 }
3741
3742 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003743 RuntimeException e = null;
3744 if (!HIDE_STACK_CRAWLS) {
3745 e = new RuntimeException();
3746 e.fillInStackTrace();
3747 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003748 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 + "): mNextAppTransition=" + mNextAppTransition
3750 + " hidden=" + wtoken.hidden
3751 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3752 }
Romain Guy06882f82009-06-10 13:36:04 -07003753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003754 // If we are preparing an app transition, then delay changing
3755 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003756 if (!mDisplayFrozen && mPolicy.isScreenOn()
3757 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 // Already in requested state, don't do anything more.
3759 if (wtoken.hiddenRequested != visible) {
3760 return;
3761 }
3762 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003763
Joe Onorato8a9b2202010-02-26 18:56:32 -08003764 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 TAG, "Setting dummy animation on: " + wtoken);
3766 wtoken.setDummyAnimation();
3767 mOpeningApps.remove(wtoken);
3768 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003769 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 wtoken.inPendingTransaction = true;
3771 if (visible) {
3772 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 wtoken.startingDisplayed = false;
3774 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003775
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003776 // If the token is currently hidden (should be the
3777 // common case), then we need to set up to wait for
3778 // its windows to be ready.
3779 if (wtoken.hidden) {
3780 wtoken.allDrawn = false;
3781 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003782
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003783 if (wtoken.clientHidden) {
3784 // In the case where we are making an app visible
3785 // but holding off for a transition, we still need
3786 // to tell the client to make its windows visible so
3787 // they get drawn. Otherwise, we will wait on
3788 // performing the transition until all windows have
3789 // been drawn, they never will be, and we are sad.
3790 wtoken.clientHidden = false;
3791 wtoken.sendAppVisibilityToClients();
3792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 }
3794 } else {
3795 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003796
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003797 // If the token is currently visible (should be the
3798 // common case), then set up to wait for it to be hidden.
3799 if (!wtoken.hidden) {
3800 wtoken.waitingToHide = true;
3801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 }
3803 return;
3804 }
Romain Guy06882f82009-06-10 13:36:04 -07003805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003807 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 wtoken.updateReportedVisibilityLocked();
3809 Binder.restoreCallingIdentity(origId);
3810 }
3811 }
3812
3813 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3814 boolean unfreezeSurfaceNow, boolean force) {
3815 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003816 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003817 + " force=" + force);
3818 final int N = wtoken.allAppWindows.size();
3819 boolean unfrozeWindows = false;
3820 for (int i=0; i<N; i++) {
3821 WindowState w = wtoken.allAppWindows.get(i);
3822 if (w.mAppFreezing) {
3823 w.mAppFreezing = false;
3824 if (w.mSurface != null && !w.mOrientationChanging) {
3825 w.mOrientationChanging = true;
3826 }
3827 unfrozeWindows = true;
3828 }
3829 }
3830 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003831 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 wtoken.freezingScreen = false;
3833 mAppsFreezingScreen--;
3834 }
3835 if (unfreezeSurfaceNow) {
3836 if (unfrozeWindows) {
3837 mLayoutNeeded = true;
3838 performLayoutAndPlaceSurfacesLocked();
3839 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003840 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 }
3842 }
3843 }
Romain Guy06882f82009-06-10 13:36:04 -07003844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3846 int configChanges) {
3847 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003848 RuntimeException e = null;
3849 if (!HIDE_STACK_CRAWLS) {
3850 e = new RuntimeException();
3851 e.fillInStackTrace();
3852 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003853 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 + ": hidden=" + wtoken.hidden + " freezing="
3855 + wtoken.freezingScreen, e);
3856 }
3857 if (!wtoken.hiddenRequested) {
3858 if (!wtoken.freezingScreen) {
3859 wtoken.freezingScreen = true;
3860 mAppsFreezingScreen++;
3861 if (mAppsFreezingScreen == 1) {
3862 startFreezingDisplayLocked();
3863 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3864 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3865 5000);
3866 }
3867 }
3868 final int N = wtoken.allAppWindows.size();
3869 for (int i=0; i<N; i++) {
3870 WindowState w = wtoken.allAppWindows.get(i);
3871 w.mAppFreezing = true;
3872 }
3873 }
3874 }
Romain Guy06882f82009-06-10 13:36:04 -07003875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 public void startAppFreezingScreen(IBinder token, int configChanges) {
3877 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3878 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003879 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 }
3881
3882 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003883 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003884 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 return;
3886 }
Romain Guy06882f82009-06-10 13:36:04 -07003887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 AppWindowToken wtoken = findAppWindowToken(token);
3889 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003890 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003891 return;
3892 }
3893 final long origId = Binder.clearCallingIdentity();
3894 startAppFreezingScreenLocked(wtoken, configChanges);
3895 Binder.restoreCallingIdentity(origId);
3896 }
3897 }
Romain Guy06882f82009-06-10 13:36:04 -07003898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 public void stopAppFreezingScreen(IBinder token, boolean force) {
3900 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3901 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003902 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 }
3904
3905 synchronized(mWindowMap) {
3906 AppWindowToken wtoken = findAppWindowToken(token);
3907 if (wtoken == null || wtoken.appToken == null) {
3908 return;
3909 }
3910 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003911 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3913 unsetAppFreezingScreenLocked(wtoken, true, force);
3914 Binder.restoreCallingIdentity(origId);
3915 }
3916 }
Romain Guy06882f82009-06-10 13:36:04 -07003917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 public void removeAppToken(IBinder token) {
3919 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3920 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003921 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 }
3923
3924 AppWindowToken wtoken = null;
3925 AppWindowToken startingToken = null;
3926 boolean delayed = false;
3927
3928 final long origId = Binder.clearCallingIdentity();
3929 synchronized(mWindowMap) {
3930 WindowToken basewtoken = mTokenMap.remove(token);
3931 mTokenList.remove(basewtoken);
3932 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003933 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003934 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 wtoken.inPendingTransaction = false;
3936 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003937 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 if (mClosingApps.contains(wtoken)) {
3939 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003940 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003942 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 delayed = true;
3944 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003945 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 TAG, "Removing app " + wtoken + " delayed=" + delayed
3947 + " animation=" + wtoken.animation
3948 + " animating=" + wtoken.animating);
3949 if (delayed) {
3950 // set the token aside because it has an active animation to be finished
3951 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003952 } else {
3953 // Make sure there is no animation running on this token,
3954 // so any windows associated with it will be removed as
3955 // soon as their animations are complete
3956 wtoken.animation = null;
3957 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003960 if (mLastEnterAnimToken == wtoken) {
3961 mLastEnterAnimToken = null;
3962 mLastEnterAnimParams = null;
3963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 wtoken.removed = true;
3965 if (wtoken.startingData != null) {
3966 startingToken = wtoken;
3967 }
3968 unsetAppFreezingScreenLocked(wtoken, true, true);
3969 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003970 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 mFocusedApp = null;
3972 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown349703e2010-06-22 01:27:15 -07003973 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3974 mInputMonitor.setFocusedAppLw(null);
3975 } else {
3976 mKeyWaiter.tickle();
3977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 }
3979 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003980 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 }
Romain Guy06882f82009-06-10 13:36:04 -07003982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 if (!delayed && wtoken != null) {
3984 wtoken.updateReportedVisibilityLocked();
3985 }
3986 }
3987 Binder.restoreCallingIdentity(origId);
3988
3989 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003990 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 + startingToken + ": app token removed");
3992 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3993 mH.sendMessage(m);
3994 }
3995 }
3996
3997 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3998 final int NW = token.windows.size();
3999 for (int i=0; i<NW; i++) {
4000 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004001 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 mWindows.remove(win);
4003 int j = win.mChildWindows.size();
4004 while (j > 0) {
4005 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004006 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004007 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004008 "Tmp removing child window " + cwin);
4009 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 }
4011 }
4012 return NW > 0;
4013 }
4014
4015 void dumpAppTokensLocked() {
4016 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004017 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 }
4019 }
Romain Guy06882f82009-06-10 13:36:04 -07004020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 void dumpWindowsLocked() {
4022 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 }
4025 }
Romain Guy06882f82009-06-10 13:36:04 -07004026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 private int findWindowOffsetLocked(int tokenPos) {
4028 final int NW = mWindows.size();
4029
4030 if (tokenPos >= mAppTokens.size()) {
4031 int i = NW;
4032 while (i > 0) {
4033 i--;
4034 WindowState win = (WindowState)mWindows.get(i);
4035 if (win.getAppToken() != null) {
4036 return i+1;
4037 }
4038 }
4039 }
4040
4041 while (tokenPos > 0) {
4042 // Find the first app token below the new position that has
4043 // a window displayed.
4044 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004045 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004047 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004048 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004049 "Skipping token -- currently sending to bottom");
4050 tokenPos--;
4051 continue;
4052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 int i = wtoken.windows.size();
4054 while (i > 0) {
4055 i--;
4056 WindowState win = wtoken.windows.get(i);
4057 int j = win.mChildWindows.size();
4058 while (j > 0) {
4059 j--;
4060 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004061 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004062 for (int pos=NW-1; pos>=0; pos--) {
4063 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004064 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 "Found child win @" + (pos+1));
4066 return pos+1;
4067 }
4068 }
4069 }
4070 }
4071 for (int pos=NW-1; pos>=0; pos--) {
4072 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004073 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 return pos+1;
4075 }
4076 }
4077 }
4078 tokenPos--;
4079 }
4080
4081 return 0;
4082 }
4083
4084 private final int reAddWindowLocked(int index, WindowState win) {
4085 final int NCW = win.mChildWindows.size();
4086 boolean added = false;
4087 for (int j=0; j<NCW; j++) {
4088 WindowState cwin = (WindowState)win.mChildWindows.get(j);
4089 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004091 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 mWindows.add(index, win);
4093 index++;
4094 added = true;
4095 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004096 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004097 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 mWindows.add(index, cwin);
4099 index++;
4100 }
4101 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004102 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004103 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 mWindows.add(index, win);
4105 index++;
4106 }
4107 return index;
4108 }
Romain Guy06882f82009-06-10 13:36:04 -07004109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4111 final int NW = token.windows.size();
4112 for (int i=0; i<NW; i++) {
4113 index = reAddWindowLocked(index, token.windows.get(i));
4114 }
4115 return index;
4116 }
4117
4118 public void moveAppToken(int index, IBinder token) {
4119 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4120 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004121 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123
4124 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004125 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 if (DEBUG_REORDER) dumpAppTokensLocked();
4127 final AppWindowToken wtoken = findAppWindowToken(token);
4128 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004129 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 + token + " (" + wtoken + ")");
4131 return;
4132 }
4133 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004134 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004138 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004139 if (DEBUG_REORDER) dumpWindowsLocked();
4140 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004141 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004142 if (DEBUG_REORDER) dumpWindowsLocked();
4143 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004144 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 if (DEBUG_REORDER) dumpWindowsLocked();
4146 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 mLayoutNeeded = true;
4148 performLayoutAndPlaceSurfacesLocked();
4149 }
4150 Binder.restoreCallingIdentity(origId);
4151 }
4152 }
4153
4154 private void removeAppTokensLocked(List<IBinder> tokens) {
4155 // XXX This should be done more efficiently!
4156 // (take advantage of the fact that both lists should be
4157 // ordered in the same way.)
4158 int N = tokens.size();
4159 for (int i=0; i<N; i++) {
4160 IBinder token = tokens.get(i);
4161 final AppWindowToken wtoken = findAppWindowToken(token);
4162 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004163 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 + token + " (" + wtoken + ")");
4165 i--;
4166 N--;
4167 }
4168 }
4169 }
4170
Dianne Hackborna8f60182009-09-01 19:01:50 -07004171 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4172 boolean updateFocusAndLayout) {
4173 // First remove all of the windows from the list.
4174 tmpRemoveAppWindowsLocked(wtoken);
4175
4176 // Where to start adding?
4177 int pos = findWindowOffsetLocked(tokenPos);
4178
4179 // And now add them back at the correct place.
4180 pos = reAddAppWindowsLocked(pos, wtoken);
4181
4182 if (updateFocusAndLayout) {
4183 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4184 assignLayersLocked();
4185 }
4186 mLayoutNeeded = true;
4187 performLayoutAndPlaceSurfacesLocked();
4188 }
4189 }
4190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4192 // First remove all of the windows from the list.
4193 final int N = tokens.size();
4194 int i;
4195 for (i=0; i<N; i++) {
4196 WindowToken token = mTokenMap.get(tokens.get(i));
4197 if (token != null) {
4198 tmpRemoveAppWindowsLocked(token);
4199 }
4200 }
4201
4202 // Where to start adding?
4203 int pos = findWindowOffsetLocked(tokenPos);
4204
4205 // And now add them back at the correct place.
4206 for (i=0; i<N; i++) {
4207 WindowToken token = mTokenMap.get(tokens.get(i));
4208 if (token != null) {
4209 pos = reAddAppWindowsLocked(pos, token);
4210 }
4211 }
4212
Dianne Hackborna8f60182009-09-01 19:01:50 -07004213 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4214 assignLayersLocked();
4215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 mLayoutNeeded = true;
4217 performLayoutAndPlaceSurfacesLocked();
4218
4219 //dump();
4220 }
4221
4222 public void moveAppTokensToTop(List<IBinder> tokens) {
4223 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4224 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004225 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 }
4227
4228 final long origId = Binder.clearCallingIdentity();
4229 synchronized(mWindowMap) {
4230 removeAppTokensLocked(tokens);
4231 final int N = tokens.size();
4232 for (int i=0; i<N; i++) {
4233 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4234 if (wt != null) {
4235 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004236 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004237 mToTopApps.remove(wt);
4238 mToBottomApps.remove(wt);
4239 mToTopApps.add(wt);
4240 wt.sendingToBottom = false;
4241 wt.sendingToTop = true;
4242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004243 }
4244 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004245
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004246 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004247 moveAppWindowsLocked(tokens, mAppTokens.size());
4248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004249 }
4250 Binder.restoreCallingIdentity(origId);
4251 }
4252
4253 public void moveAppTokensToBottom(List<IBinder> tokens) {
4254 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4255 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004256 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 }
4258
4259 final long origId = Binder.clearCallingIdentity();
4260 synchronized(mWindowMap) {
4261 removeAppTokensLocked(tokens);
4262 final int N = tokens.size();
4263 int pos = 0;
4264 for (int i=0; i<N; i++) {
4265 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4266 if (wt != null) {
4267 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004268 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004269 mToTopApps.remove(wt);
4270 mToBottomApps.remove(wt);
4271 mToBottomApps.add(i, wt);
4272 wt.sendingToTop = false;
4273 wt.sendingToBottom = true;
4274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 pos++;
4276 }
4277 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004278
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004279 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004280 moveAppWindowsLocked(tokens, 0);
4281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004282 }
4283 Binder.restoreCallingIdentity(origId);
4284 }
4285
4286 // -------------------------------------------------------------
4287 // Misc IWindowSession methods
4288 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004289
Jim Miller284b62e2010-06-08 14:27:42 -07004290 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004291 {
Jim Miller284b62e2010-06-08 14:27:42 -07004292 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4293 // called before DevicePolicyManagerService has started.
4294 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4295 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4296 Context.DEVICE_POLICY_SERVICE);
4297 if (dpm != null) {
4298 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4299 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4300 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4301 }
Jim Millerd6b57052010-06-07 17:52:42 -07004302 }
Jim Miller284b62e2010-06-08 14:27:42 -07004303 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004304 }
4305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004307 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 != PackageManager.PERMISSION_GRANTED) {
4309 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4310 }
Jim Millerd6b57052010-06-07 17:52:42 -07004311
Jim Miller284b62e2010-06-08 14:27:42 -07004312 synchronized (mKeyguardTokenWatcher) {
4313 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 }
4316
4317 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004318 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 != PackageManager.PERMISSION_GRANTED) {
4320 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004322
Jim Miller284b62e2010-06-08 14:27:42 -07004323 synchronized (mKeyguardTokenWatcher) {
4324 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004325
Jim Miller284b62e2010-06-08 14:27:42 -07004326 if (!mKeyguardTokenWatcher.isAcquired()) {
4327 // If we are the last one to reenable the keyguard wait until
4328 // we have actually finished reenabling until returning.
4329 // It is possible that reenableKeyguard() can be called before
4330 // the previous disableKeyguard() is handled, in which case
4331 // neither mKeyguardTokenWatcher.acquired() or released() would
4332 // be called. In that case mKeyguardDisabled will be false here
4333 // and we have nothing to wait for.
4334 while (mKeyguardDisabled) {
4335 try {
4336 mKeyguardTokenWatcher.wait();
4337 } catch (InterruptedException e) {
4338 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004339 }
4340 }
4341 }
4342 }
4343 }
4344
4345 /**
4346 * @see android.app.KeyguardManager#exitKeyguardSecurely
4347 */
4348 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004349 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 != PackageManager.PERMISSION_GRANTED) {
4351 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4352 }
4353 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4354 public void onKeyguardExitResult(boolean success) {
4355 try {
4356 callback.onKeyguardExitResult(success);
4357 } catch (RemoteException e) {
4358 // Client has died, we don't care.
4359 }
4360 }
4361 });
4362 }
4363
4364 public boolean inKeyguardRestrictedInputMode() {
4365 return mPolicy.inKeyguardRestrictedKeyInputMode();
4366 }
Romain Guy06882f82009-06-10 13:36:04 -07004367
Dianne Hackbornffa42482009-09-23 22:20:11 -07004368 public void closeSystemDialogs(String reason) {
4369 synchronized(mWindowMap) {
4370 for (int i=mWindows.size()-1; i>=0; i--) {
4371 WindowState w = (WindowState)mWindows.get(i);
4372 if (w.mSurface != null) {
4373 try {
4374 w.mClient.closeSystemDialogs(reason);
4375 } catch (RemoteException e) {
4376 }
4377 }
4378 }
4379 }
4380 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 static float fixScale(float scale) {
4383 if (scale < 0) scale = 0;
4384 else if (scale > 20) scale = 20;
4385 return Math.abs(scale);
4386 }
Romain Guy06882f82009-06-10 13:36:04 -07004387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 public void setAnimationScale(int which, float scale) {
4389 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4390 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004391 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392 }
4393
4394 if (scale < 0) scale = 0;
4395 else if (scale > 20) scale = 20;
4396 scale = Math.abs(scale);
4397 switch (which) {
4398 case 0: mWindowAnimationScale = fixScale(scale); break;
4399 case 1: mTransitionAnimationScale = fixScale(scale); break;
4400 }
Romain Guy06882f82009-06-10 13:36:04 -07004401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 // Persist setting
4403 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4404 }
Romain Guy06882f82009-06-10 13:36:04 -07004405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004406 public void setAnimationScales(float[] scales) {
4407 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4408 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004409 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
4411
4412 if (scales != null) {
4413 if (scales.length >= 1) {
4414 mWindowAnimationScale = fixScale(scales[0]);
4415 }
4416 if (scales.length >= 2) {
4417 mTransitionAnimationScale = fixScale(scales[1]);
4418 }
4419 }
Romain Guy06882f82009-06-10 13:36:04 -07004420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 // Persist setting
4422 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4423 }
Romain Guy06882f82009-06-10 13:36:04 -07004424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 public float getAnimationScale(int which) {
4426 switch (which) {
4427 case 0: return mWindowAnimationScale;
4428 case 1: return mTransitionAnimationScale;
4429 }
4430 return 0;
4431 }
Romain Guy06882f82009-06-10 13:36:04 -07004432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 public float[] getAnimationScales() {
4434 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4435 }
Romain Guy06882f82009-06-10 13:36:04 -07004436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 public int getSwitchState(int sw) {
4438 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4439 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004440 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004441 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004442 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4443 return mInputManager.getSwitchState(sw);
4444 } else {
4445 return KeyInputQueue.getSwitchState(sw);
4446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 }
Romain Guy06882f82009-06-10 13:36:04 -07004448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 public int getSwitchStateForDevice(int devid, int sw) {
4450 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4451 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004452 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004454 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4455 return mInputManager.getSwitchState(devid, sw);
4456 } else {
4457 return KeyInputQueue.getSwitchState(devid, sw);
4458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 }
Romain Guy06882f82009-06-10 13:36:04 -07004460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 public int getScancodeState(int sw) {
4462 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4463 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004464 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004466 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4467 return mInputManager.getScancodeState(sw);
4468 } else {
4469 return mQueue.getScancodeState(sw);
4470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471 }
Romain Guy06882f82009-06-10 13:36:04 -07004472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 public int getScancodeStateForDevice(int devid, int sw) {
4474 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4475 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004476 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004478 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4479 return mInputManager.getScancodeState(devid, sw);
4480 } else {
4481 return mQueue.getScancodeState(devid, sw);
4482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004483 }
Romain Guy06882f82009-06-10 13:36:04 -07004484
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004485 public int getTrackballScancodeState(int sw) {
4486 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4487 "getTrackballScancodeState()")) {
4488 throw new SecurityException("Requires READ_INPUT_STATE permission");
4489 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004490 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4491 return mInputManager.getTrackballScancodeState(sw);
4492 } else {
4493 return mQueue.getTrackballScancodeState(sw);
4494 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004495 }
4496
4497 public int getDPadScancodeState(int sw) {
4498 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4499 "getDPadScancodeState()")) {
4500 throw new SecurityException("Requires READ_INPUT_STATE permission");
4501 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004502 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4503 return mInputManager.getDPadScancodeState(sw);
4504 } else {
4505 return mQueue.getDPadScancodeState(sw);
4506 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004507 }
4508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 public int getKeycodeState(int sw) {
4510 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4511 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004512 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004514 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4515 return mInputManager.getKeycodeState(sw);
4516 } else {
4517 return mQueue.getKeycodeState(sw);
4518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 }
Romain Guy06882f82009-06-10 13:36:04 -07004520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 public int getKeycodeStateForDevice(int devid, int sw) {
4522 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4523 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004524 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004526 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4527 return mInputManager.getKeycodeState(devid, sw);
4528 } else {
4529 return mQueue.getKeycodeState(devid, sw);
4530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 }
Romain Guy06882f82009-06-10 13:36:04 -07004532
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004533 public int getTrackballKeycodeState(int sw) {
4534 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4535 "getTrackballKeycodeState()")) {
4536 throw new SecurityException("Requires READ_INPUT_STATE permission");
4537 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004538 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4539 return mInputManager.getTrackballKeycodeState(sw);
4540 } else {
4541 return mQueue.getTrackballKeycodeState(sw);
4542 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004543 }
4544
4545 public int getDPadKeycodeState(int sw) {
4546 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4547 "getDPadKeycodeState()")) {
4548 throw new SecurityException("Requires READ_INPUT_STATE permission");
4549 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07004550 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4551 return mInputManager.getDPadKeycodeState(sw);
4552 } else {
4553 return mQueue.getDPadKeycodeState(sw);
4554 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004555 }
4556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004558 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4559 return mInputManager.hasKeys(keycodes, keyExists);
4560 } else {
4561 return KeyInputQueue.hasKeys(keycodes, keyExists);
4562 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 }
Romain Guy06882f82009-06-10 13:36:04 -07004564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004565 public void enableScreenAfterBoot() {
4566 synchronized(mWindowMap) {
4567 if (mSystemBooted) {
4568 return;
4569 }
4570 mSystemBooted = true;
4571 }
Romain Guy06882f82009-06-10 13:36:04 -07004572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 performEnableScreen();
4574 }
Romain Guy06882f82009-06-10 13:36:04 -07004575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 public void enableScreenIfNeededLocked() {
4577 if (mDisplayEnabled) {
4578 return;
4579 }
4580 if (!mSystemBooted) {
4581 return;
4582 }
4583 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4584 }
Romain Guy06882f82009-06-10 13:36:04 -07004585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 public void performEnableScreen() {
4587 synchronized(mWindowMap) {
4588 if (mDisplayEnabled) {
4589 return;
4590 }
4591 if (!mSystemBooted) {
4592 return;
4593 }
Romain Guy06882f82009-06-10 13:36:04 -07004594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 // Don't enable the screen until all existing windows
4596 // have been drawn.
4597 final int N = mWindows.size();
4598 for (int i=0; i<N; i++) {
4599 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn5943c202010-04-12 21:36:49 -07004600 if (w.isVisibleLw() && !w.mObscured
4601 && (w.mOrientationChanging || !w.isDrawnLw())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 return;
4603 }
4604 }
Romain Guy06882f82009-06-10 13:36:04 -07004605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 mDisplayEnabled = true;
4607 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004608 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 StringWriter sw = new StringWriter();
4610 PrintWriter pw = new PrintWriter(sw);
4611 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004612 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 }
4614 try {
4615 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4616 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004617 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 Parcel data = Parcel.obtain();
4619 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4620 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4621 data, null, 0);
4622 data.recycle();
4623 }
4624 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004625 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627 }
Romain Guy06882f82009-06-10 13:36:04 -07004628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004632 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4633 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
Romain Guy06882f82009-06-10 13:36:04 -07004635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 public void setInTouchMode(boolean mode) {
4637 synchronized(mWindowMap) {
4638 mInTouchMode = mode;
4639 }
4640 }
4641
Romain Guy06882f82009-06-10 13:36:04 -07004642 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004643 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004644 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004645 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004646 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
4648
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004649 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
Romain Guy06882f82009-06-10 13:36:04 -07004651
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004652 public void setRotationUnchecked(int rotation,
4653 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004654 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 long origId = Binder.clearCallingIdentity();
4658 boolean changed;
4659 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004660 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 }
Romain Guy06882f82009-06-10 13:36:04 -07004662
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004663 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 sendNewConfiguration();
4665 }
Romain Guy06882f82009-06-10 13:36:04 -07004666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 Binder.restoreCallingIdentity(origId);
4668 }
Romain Guy06882f82009-06-10 13:36:04 -07004669
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004670 /**
4671 * Apply a new rotation to the screen, respecting the requests of
4672 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4673 * re-evaluate the desired rotation.
4674 *
4675 * Returns null if the rotation has been changed. In this case YOU
4676 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4677 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004678 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 boolean changed;
4680 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4681 rotation = mRequestedRotation;
4682 } else {
4683 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004684 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004686 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004687 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004689 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004693 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 "Rotation changed to " + rotation
4695 + " from " + mRotation
4696 + " (forceApp=" + mForcedAppOrientation
4697 + ", req=" + mRequestedRotation + ")");
4698 mRotation = rotation;
4699 mWindowsFreezingScreen = true;
4700 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4701 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4702 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004703 mWaitingForConfig = true;
4704 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004706 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07004707 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4708 mInputManager.setDisplayOrientation(0, rotation);
4709 } else {
4710 mQueue.setOrientation(rotation);
4711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004713 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004714 }
4715 for (int i=mWindows.size()-1; i>=0; i--) {
4716 WindowState w = (WindowState)mWindows.get(i);
4717 if (w.mSurface != null) {
4718 w.mOrientationChanging = true;
4719 }
4720 }
4721 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4722 try {
4723 mRotationWatchers.get(i).onRotationChanged(rotation);
4724 } catch (RemoteException e) {
4725 }
4726 }
4727 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 return changed;
4730 }
Romain Guy06882f82009-06-10 13:36:04 -07004731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 public int getRotation() {
4733 return mRotation;
4734 }
4735
4736 public int watchRotation(IRotationWatcher watcher) {
4737 final IBinder watcherBinder = watcher.asBinder();
4738 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4739 public void binderDied() {
4740 synchronized (mWindowMap) {
4741 for (int i=0; i<mRotationWatchers.size(); i++) {
4742 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004743 IRotationWatcher removed = mRotationWatchers.remove(i);
4744 if (removed != null) {
4745 removed.asBinder().unlinkToDeath(this, 0);
4746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 i--;
4748 }
4749 }
4750 }
4751 }
4752 };
Romain Guy06882f82009-06-10 13:36:04 -07004753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 synchronized (mWindowMap) {
4755 try {
4756 watcher.asBinder().linkToDeath(dr, 0);
4757 mRotationWatchers.add(watcher);
4758 } catch (RemoteException e) {
4759 // Client died, no cleanup needed.
4760 }
Romain Guy06882f82009-06-10 13:36:04 -07004761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 return mRotation;
4763 }
4764 }
4765
4766 /**
4767 * Starts the view server on the specified port.
4768 *
4769 * @param port The port to listener to.
4770 *
4771 * @return True if the server was successfully started, false otherwise.
4772 *
4773 * @see com.android.server.ViewServer
4774 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4775 */
4776 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004777 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 return false;
4779 }
4780
4781 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4782 return false;
4783 }
4784
4785 if (port < 1024) {
4786 return false;
4787 }
4788
4789 if (mViewServer != null) {
4790 if (!mViewServer.isRunning()) {
4791 try {
4792 return mViewServer.start();
4793 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004794 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 }
4796 }
4797 return false;
4798 }
4799
4800 try {
4801 mViewServer = new ViewServer(this, port);
4802 return mViewServer.start();
4803 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004804 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 }
4806 return false;
4807 }
4808
Romain Guy06882f82009-06-10 13:36:04 -07004809 private boolean isSystemSecure() {
4810 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4811 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4812 }
4813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 /**
4815 * Stops the view server if it exists.
4816 *
4817 * @return True if the server stopped, false if it wasn't started or
4818 * couldn't be stopped.
4819 *
4820 * @see com.android.server.ViewServer
4821 */
4822 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004823 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 return false;
4825 }
4826
4827 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4828 return false;
4829 }
4830
4831 if (mViewServer != null) {
4832 return mViewServer.stop();
4833 }
4834 return false;
4835 }
4836
4837 /**
4838 * Indicates whether the view server is running.
4839 *
4840 * @return True if the server is running, false otherwise.
4841 *
4842 * @see com.android.server.ViewServer
4843 */
4844 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004845 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 return false;
4847 }
4848
4849 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4850 return false;
4851 }
4852
4853 return mViewServer != null && mViewServer.isRunning();
4854 }
4855
4856 /**
4857 * Lists all availble windows in the system. The listing is written in the
4858 * specified Socket's output stream with the following syntax:
4859 * windowHashCodeInHexadecimal windowName
4860 * Each line of the ouput represents a different window.
4861 *
4862 * @param client The remote client to send the listing to.
4863 * @return False if an error occured, true otherwise.
4864 */
4865 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004866 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 return false;
4868 }
4869
4870 boolean result = true;
4871
4872 Object[] windows;
4873 synchronized (mWindowMap) {
4874 windows = new Object[mWindows.size()];
4875 //noinspection unchecked
4876 windows = mWindows.toArray(windows);
4877 }
4878
4879 BufferedWriter out = null;
4880
4881 // Any uncaught exception will crash the system process
4882 try {
4883 OutputStream clientStream = client.getOutputStream();
4884 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4885
4886 final int count = windows.length;
4887 for (int i = 0; i < count; i++) {
4888 final WindowState w = (WindowState) windows[i];
4889 out.write(Integer.toHexString(System.identityHashCode(w)));
4890 out.write(' ');
4891 out.append(w.mAttrs.getTitle());
4892 out.write('\n');
4893 }
4894
4895 out.write("DONE.\n");
4896 out.flush();
4897 } catch (Exception e) {
4898 result = false;
4899 } finally {
4900 if (out != null) {
4901 try {
4902 out.close();
4903 } catch (IOException e) {
4904 result = false;
4905 }
4906 }
4907 }
4908
4909 return result;
4910 }
4911
4912 /**
4913 * Sends a command to a target window. The result of the command, if any, will be
4914 * written in the output stream of the specified socket.
4915 *
4916 * The parameters must follow this syntax:
4917 * windowHashcode extra
4918 *
4919 * Where XX is the length in characeters of the windowTitle.
4920 *
4921 * The first parameter is the target window. The window with the specified hashcode
4922 * will be the target. If no target can be found, nothing happens. The extra parameters
4923 * will be delivered to the target window and as parameters to the command itself.
4924 *
4925 * @param client The remote client to sent the result, if any, to.
4926 * @param command The command to execute.
4927 * @param parameters The command parameters.
4928 *
4929 * @return True if the command was successfully delivered, false otherwise. This does
4930 * not indicate whether the command itself was successful.
4931 */
4932 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004933 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 return false;
4935 }
4936
4937 boolean success = true;
4938 Parcel data = null;
4939 Parcel reply = null;
4940
4941 // Any uncaught exception will crash the system process
4942 try {
4943 // Find the hashcode of the window
4944 int index = parameters.indexOf(' ');
4945 if (index == -1) {
4946 index = parameters.length();
4947 }
4948 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004949 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950
4951 // Extract the command's parameter after the window description
4952 if (index < parameters.length()) {
4953 parameters = parameters.substring(index + 1);
4954 } else {
4955 parameters = "";
4956 }
4957
4958 final WindowManagerService.WindowState window = findWindow(hashCode);
4959 if (window == null) {
4960 return false;
4961 }
4962
4963 data = Parcel.obtain();
4964 data.writeInterfaceToken("android.view.IWindow");
4965 data.writeString(command);
4966 data.writeString(parameters);
4967 data.writeInt(1);
4968 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4969
4970 reply = Parcel.obtain();
4971
4972 final IBinder binder = window.mClient.asBinder();
4973 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4974 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4975
4976 reply.readException();
4977
4978 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004979 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 success = false;
4981 } finally {
4982 if (data != null) {
4983 data.recycle();
4984 }
4985 if (reply != null) {
4986 reply.recycle();
4987 }
4988 }
4989
4990 return success;
4991 }
4992
4993 private WindowState findWindow(int hashCode) {
4994 if (hashCode == -1) {
4995 return getFocusedWindow();
4996 }
4997
4998 synchronized (mWindowMap) {
4999 final ArrayList windows = mWindows;
5000 final int count = windows.size();
5001
5002 for (int i = 0; i < count; i++) {
5003 WindowState w = (WindowState) windows.get(i);
5004 if (System.identityHashCode(w) == hashCode) {
5005 return w;
5006 }
5007 }
5008 }
5009
5010 return null;
5011 }
5012
5013 /*
5014 * Instruct the Activity Manager to fetch the current configuration and broadcast
5015 * that to config-changed listeners if appropriate.
5016 */
5017 void sendNewConfiguration() {
5018 try {
5019 mActivityManager.updateConfiguration(null);
5020 } catch (RemoteException e) {
5021 }
5022 }
Romain Guy06882f82009-06-10 13:36:04 -07005023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 public Configuration computeNewConfiguration() {
5025 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005026 return computeNewConfigurationLocked();
5027 }
5028 }
Romain Guy06882f82009-06-10 13:36:04 -07005029
Dianne Hackbornc485a602009-03-24 22:39:49 -07005030 Configuration computeNewConfigurationLocked() {
5031 Configuration config = new Configuration();
5032 if (!computeNewConfigurationLocked(config)) {
5033 return null;
5034 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005035 return config;
5036 }
Romain Guy06882f82009-06-10 13:36:04 -07005037
Dianne Hackbornc485a602009-03-24 22:39:49 -07005038 boolean computeNewConfigurationLocked(Configuration config) {
5039 if (mDisplay == null) {
5040 return false;
5041 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07005042 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5043 mInputManager.getInputConfiguration(config);
5044 } else {
5045 mQueue.getInputConfiguration(config);
5046 }
Christopher Tateb696aee2010-04-02 19:08:30 -07005047
5048 // Use the effective "visual" dimensions based on current rotation
5049 final boolean rotated = (mRotation == Surface.ROTATION_90
5050 || mRotation == Surface.ROTATION_270);
5051 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5052 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5053
Dianne Hackbornc485a602009-03-24 22:39:49 -07005054 int orientation = Configuration.ORIENTATION_SQUARE;
5055 if (dw < dh) {
5056 orientation = Configuration.ORIENTATION_PORTRAIT;
5057 } else if (dw > dh) {
5058 orientation = Configuration.ORIENTATION_LANDSCAPE;
5059 }
5060 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005061
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005062 DisplayMetrics dm = new DisplayMetrics();
5063 mDisplay.getMetrics(dm);
5064 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5065
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005066 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005067 // Note we only do this once because at this point we don't
5068 // expect the screen to change in this way at runtime, and want
5069 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005070 int longSize = dw;
5071 int shortSize = dh;
5072 if (longSize < shortSize) {
5073 int tmp = longSize;
5074 longSize = shortSize;
5075 shortSize = tmp;
5076 }
5077 longSize = (int)(longSize/dm.density);
5078 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005079
Dianne Hackborn723738c2009-06-25 19:48:04 -07005080 // These semi-magic numbers define our compatibility modes for
5081 // applications with different screens. Don't change unless you
5082 // make sure to test lots and lots of apps!
5083 if (longSize < 470) {
5084 // This is shorter than an HVGA normal density screen (which
5085 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005086 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5087 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005088 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005089 // What size is this screen screen?
5090 if (longSize >= 800 && shortSize >= 600) {
5091 // SVGA or larger screens at medium density are the point
5092 // at which we consider it to be an extra large screen.
5093 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5094 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005095 // VGA or larger screens at medium density are the point
5096 // at which we consider it to be a large screen.
5097 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5098 } else {
5099 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005100
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005101 // If this screen is wider than normal HVGA, or taller
5102 // than FWVGA, then for old apps we want to run in size
5103 // compatibility mode.
5104 if (shortSize > 321 || longSize > 570) {
5105 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5106 }
5107 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005108
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005109 // Is this a long screen?
5110 if (((longSize*3)/5) >= (shortSize-1)) {
5111 // Anything wider than WVGA (5:3) is considering to be long.
5112 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5113 } else {
5114 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5115 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005116 }
5117 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005118 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005119
Dianne Hackbornc485a602009-03-24 22:39:49 -07005120 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5121 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5122 mPolicy.adjustConfigurationLw(config);
5123 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 // -------------------------------------------------------------
5127 // Input Events and Focus Management
5128 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07005129
Jeff Brown349703e2010-06-22 01:27:15 -07005130 InputMonitor mInputMonitor = new InputMonitor();
5131
5132 /* Tracks the progress of input dispatch and ensures that input dispatch state
5133 * is kept in sync with changes in window focus, visibility, registration, and
5134 * other relevant Window Manager state transitions. */
5135 final class InputMonitor {
5136 // Current window with input focus for keys and other non-touch events. May be null.
5137 private WindowState mInputFocus;
5138
5139 // When true, prevents input dispatch from proceeding until set to false again.
5140 private boolean mInputDispatchFrozen;
5141
5142 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5143 private boolean mInputDispatchEnabled = true;
5144
5145 // Temporary list of windows information to provide to the input dispatcher.
5146 private InputWindowList mTempInputWindows = new InputWindowList();
5147
5148 // Temporary input application object to provide to the input dispatcher.
5149 private InputApplication mTempInputApplication = new InputApplication();
5150
5151 /* Notifies the window manager about a broken input channel.
5152 *
5153 * Called by the InputManager.
5154 */
5155 public void notifyInputChannelBroken(InputChannel inputChannel) {
5156 synchronized (mWindowMap) {
5157 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5158 if (windowState == null) {
5159 return; // irrelevant
5160 }
5161
5162 Slog.i(TAG, "WINDOW DIED " + windowState);
5163 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005164 }
5165 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07005166
Jeff Brown349703e2010-06-22 01:27:15 -07005167 /* Notifies the window manager about an input channel that is not responding.
5168 * The method can either cause dispatching to be aborted by returning -2 or
5169 * return a new timeout in nanoseconds.
5170 *
5171 * Called by the InputManager.
5172 */
5173 public long notifyInputChannelANR(InputChannel inputChannel) {
5174 AppWindowToken token;
5175 synchronized (mWindowMap) {
5176 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5177 if (windowState == null) {
5178 return -2; // irrelevant, abort dispatching (-2)
5179 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005180
Jeff Brown349703e2010-06-22 01:27:15 -07005181 Slog.i(TAG, "Input event dispatching timed out sending to "
5182 + windowState.mAttrs.getTitle());
5183 token = windowState.mAppToken;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005184 }
5185
Jeff Brown349703e2010-06-22 01:27:15 -07005186 return notifyANRInternal(token);
5187 }
5188
5189 /* Notifies the window manager about an input channel spontaneously recovering from ANR
5190 * by successfully delivering the event that originally timed out.
5191 *
5192 * Called by the InputManager.
5193 */
5194 public void notifyInputChannelRecoveredFromANR(InputChannel inputChannel) {
5195 // Nothing to do just now.
5196 // Just wait for the user to dismiss the ANR dialog.
5197 }
5198
5199 /* Notifies the window manager about an application that is not responding
5200 * in general rather than with respect to a particular input channel.
5201 * The method can either cause dispatching to be aborted by returning -2 or
5202 * return a new timeout in nanoseconds.
5203 *
5204 * Called by the InputManager.
5205 */
5206 public long notifyANR(Object token) {
5207 AppWindowToken appWindowToken = (AppWindowToken) token;
5208
5209 Slog.i(TAG, "Input event dispatching timed out sending to application "
5210 + appWindowToken.stringName);
5211 return notifyANRInternal(appWindowToken);
5212 }
5213
5214 private long notifyANRInternal(AppWindowToken token) {
5215 if (token != null && token.appToken != null) {
5216 try {
5217 // Notify the activity manager about the timeout and let it decide whether
5218 // to abort dispatching or keep waiting.
5219 boolean abort = token.appToken.keyDispatchingTimedOut();
5220 if (! abort) {
5221 // The activity manager declined to abort dispatching.
5222 // Wait a bit longer and timeout again later.
5223 return token.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005224 }
Jeff Brown349703e2010-06-22 01:27:15 -07005225 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005226 }
5227 }
Jeff Brown349703e2010-06-22 01:27:15 -07005228 return -2; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005229 }
5230
Jeff Brown349703e2010-06-22 01:27:15 -07005231 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5232 synchronized (mWindowMap) {
5233 return getWindowStateForInputChannelLocked(inputChannel);
5234 }
5235 }
5236
5237 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5238 int windowCount = mWindows.size();
5239 for (int i = 0; i < windowCount; i++) {
5240 WindowState windowState = (WindowState) mWindows.get(i);
5241 if (windowState.mInputChannel == inputChannel) {
5242 return windowState;
5243 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005244 }
5245
Jeff Brown349703e2010-06-22 01:27:15 -07005246 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005247 }
5248
Jeff Brown349703e2010-06-22 01:27:15 -07005249 /* Updates the cached window information provided to the input dispatcher. */
5250 public void updateInputWindowsLw() {
5251 // Populate the input window list with information about all of the windows that
5252 // could potentially receive input.
5253 // As an optimization, we could try to prune the list of windows but this turns
5254 // out to be difficult because only the native code knows for sure which window
5255 // currently has touch focus.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005256 final ArrayList windows = mWindows;
5257 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005258 for (int i = N - 1; i >= 0; i--) {
5259 final WindowState child = (WindowState) windows.get(i);
5260 if (child.mInputChannel == null) {
5261 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005262 continue;
5263 }
5264
Jeff Brown349703e2010-06-22 01:27:15 -07005265 final int flags = child.mAttrs.flags;
5266 final int type = child.mAttrs.type;
5267
5268 final boolean hasFocus = (child == mInputFocus);
5269 final boolean isVisible = child.isVisibleLw();
5270 final boolean hasWallpaper = (child == mWallpaperTarget)
5271 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
5272
5273 // Add a window to our list of input windows.
5274 final InputWindow inputWindow = mTempInputWindows.add();
5275 inputWindow.inputChannel = child.mInputChannel;
5276 inputWindow.layoutParamsFlags = flags;
5277 inputWindow.layoutParamsType = type;
5278 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5279 inputWindow.visible = isVisible;
5280 inputWindow.hasFocus = hasFocus;
5281 inputWindow.hasWallpaper = hasWallpaper;
5282 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
5283 inputWindow.ownerPid = child.mSession.mPid;
5284 inputWindow.ownerUid = child.mSession.mUid;
5285
5286 final Rect frame = child.mFrame;
5287 inputWindow.frameLeft = frame.left;
5288 inputWindow.frameTop = frame.top;
5289
5290 switch (child.mTouchableInsets) {
5291 default:
5292 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5293 inputWindow.touchableAreaLeft = frame.left;
5294 inputWindow.touchableAreaTop = frame.top;
5295 inputWindow.touchableAreaRight = frame.right;
5296 inputWindow.touchableAreaBottom = frame.bottom;
5297 break;
5298
5299 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5300 Rect inset = child.mGivenContentInsets;
5301 inputWindow.touchableAreaLeft = frame.left + inset.left;
5302 inputWindow.touchableAreaTop = frame.top + inset.top;
5303 inputWindow.touchableAreaRight = frame.right - inset.right;
5304 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5305 break;
Jeff Brown46b9ac02010-04-22 18:58:52 -07005306 }
Jeff Brown349703e2010-06-22 01:27:15 -07005307
5308 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5309 Rect inset = child.mGivenVisibleInsets;
5310 inputWindow.touchableAreaLeft = frame.left + inset.left;
5311 inputWindow.touchableAreaTop = frame.top + inset.top;
5312 inputWindow.touchableAreaRight = frame.right - inset.right;
5313 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac02010-04-22 18:58:52 -07005314 break;
5315 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07005316 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07005317 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005318
Jeff Brown349703e2010-06-22 01:27:15 -07005319 // Send windows to native code.
5320 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac02010-04-22 18:58:52 -07005321
Jeff Brown349703e2010-06-22 01:27:15 -07005322 // Clear the list in preparation for the next round.
5323 // Also avoids keeping InputChannel objects referenced unnecessarily.
5324 mTempInputWindows.clear();
5325 }
5326
5327 /* Notifies that an app switch key (BACK / HOME) has just been pressed.
5328 * This essentially starts a .5 second timeout for the application to process
5329 * subsequent input events while waiting for the app switch to occur. If it takes longer
5330 * than this, the pending events will be dropped.
5331 */
5332 public void notifyAppSwitchComing() {
5333 // TODO Not implemented yet. Should go in the native side.
5334 }
5335
5336 /* Provides an opportunity for the window manager policy to intercept early key
5337 * processing as soon as the key has been read from the device. */
5338 public int interceptKeyBeforeQueueing(int deviceId, int type, int scanCode,
5339 int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) {
5340 RawInputEvent event = new RawInputEvent();
5341 event.deviceId = deviceId;
5342 event.type = type;
5343 event.scancode = scanCode;
5344 event.keycode = keyCode;
5345 event.flags = policyFlags;
5346 event.value = value;
5347 event.when = whenNanos / 1000000;
Jeff Brown46b9ac02010-04-22 18:58:52 -07005348
Jeff Brown349703e2010-06-22 01:27:15 -07005349 return mPolicy.interceptKeyTq(event, isScreenOn);
5350 }
5351
5352 /* Provides an opportunity for the window manager policy to process a key before
5353 * ordinary dispatch. */
5354 public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode,
5355 int metaState, boolean down, int repeatCount, int policyFlags) {
5356 WindowState windowState = getWindowStateForInputChannel(focus);
5357 return mPolicy.interceptKeyTi(windowState, keyCode, metaState, down, repeatCount,
5358 policyFlags);
5359 }
5360
5361 /* Called when the current input focus changes.
5362 * Layer assignment is assumed to be complete by the time this is called.
5363 */
5364 public void setInputFocusLw(WindowState newWindow) {
5365 if (DEBUG_INPUT) {
5366 Slog.d(TAG, "Input focus has changed to " + newWindow);
5367 }
5368
5369 if (newWindow != mInputFocus) {
5370 if (newWindow != null && newWindow.canReceiveKeys()) {
5371 // If the new input focus is an error window or appears above the current
5372 // input focus, preempt any pending synchronous dispatch so that we can
5373 // start delivering events to the new input focus as soon as possible.
5374 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
5375 if (DEBUG_INPUT) {
5376 Slog.v(TAG, "New SYSTEM_ERROR window; resetting state");
Jeff Brown46b9ac02010-04-22 18:58:52 -07005377 }
Jeff Brown349703e2010-06-22 01:27:15 -07005378 preemptInputDispatchLw();
5379 } else if (mInputFocus != null && newWindow.mLayer > mInputFocus.mLayer) {
5380 if (DEBUG_INPUT) {
5381 Slog.v(TAG, "Transferring focus to new window at higher layer: "
5382 + "old win layer=" + mInputFocus.mLayer
5383 + ", new win layer=" + newWindow.mLayer);
5384 }
5385 preemptInputDispatchLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005386 }
Jeff Brown349703e2010-06-22 01:27:15 -07005387
5388 // Displaying a window implicitly causes dispatching to be unpaused.
5389 // This is to protect against bugs if someone pauses dispatching but
5390 // forgets to resume.
5391 newWindow.mToken.paused = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -07005392 }
Jeff Brown349703e2010-06-22 01:27:15 -07005393
5394 mInputFocus = newWindow;
5395 updateInputWindowsLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005396 }
5397 }
5398
Jeff Brown349703e2010-06-22 01:27:15 -07005399 public void windowIsBecomingInvisibleLw(WindowState window) {
5400 // The window is becoming invisible. Preempt input dispatch in progress
5401 // so that the next window below can receive focus.
5402 if (window == mInputFocus) {
5403 mInputFocus = null;
5404 preemptInputDispatchLw();
5405 }
5406
5407 updateInputWindowsLw();
5408 }
5409
5410 /* Tells the dispatcher to stop waiting for its current synchronous event targets.
5411 * Essentially, just makes those dispatches asynchronous so a new dispatch cycle
5412 * can begin.
5413 */
5414 private void preemptInputDispatchLw() {
5415 mInputManager.preemptInputDispatch();
5416 }
5417
5418 public void setFocusedAppLw(AppWindowToken newApp) {
5419 // Focused app has changed.
5420 if (newApp == null) {
5421 mInputManager.setFocusedApplication(null);
5422 } else {
5423 mTempInputApplication.name = newApp.toString();
5424 mTempInputApplication.dispatchingTimeoutNanos =
5425 newApp.inputDispatchingTimeoutNanos;
5426 mTempInputApplication.token = newApp;
5427
5428 mInputManager.setFocusedApplication(mTempInputApplication);
5429 }
5430 }
5431
5432 public void windowIsBeingRemovedLw(WindowState window) {
5433 // Window is being removed.
5434 updateInputWindowsLw();
5435 }
5436
5437 public void pauseDispatchingLw(WindowToken window) {
5438 if (! window.paused) {
5439 if (DEBUG_INPUT) {
5440 Slog.v(TAG, "Pausing WindowToken " + window);
5441 }
5442
5443 window.paused = true;
5444 updateInputWindowsLw();
5445 }
5446 }
5447
5448 public void resumeDispatchingLw(WindowToken window) {
5449 if (window.paused) {
5450 if (DEBUG_INPUT) {
5451 Slog.v(TAG, "Resuming WindowToken " + window);
5452 }
5453
5454 window.paused = false;
5455 updateInputWindowsLw();
5456 }
5457 }
5458
5459 public void freezeInputDispatchingLw() {
5460 if (! mInputDispatchFrozen) {
5461 if (DEBUG_INPUT) {
5462 Slog.v(TAG, "Freezing input dispatching");
5463 }
5464
5465 mInputDispatchFrozen = true;
5466 updateInputDispatchModeLw();
5467 }
5468 }
5469
5470 public void thawInputDispatchingLw() {
5471 if (mInputDispatchFrozen) {
5472 if (DEBUG_INPUT) {
5473 Slog.v(TAG, "Thawing input dispatching");
5474 }
5475
5476 mInputDispatchFrozen = false;
5477 updateInputDispatchModeLw();
5478 }
5479 }
5480
5481 public void setEventDispatchingLw(boolean enabled) {
5482 if (mInputDispatchEnabled != enabled) {
5483 if (DEBUG_INPUT) {
5484 Slog.v(TAG, "Setting event dispatching to " + enabled);
5485 }
5486
5487 mInputDispatchEnabled = enabled;
5488 updateInputDispatchModeLw();
5489 }
5490 }
5491
5492 private void updateInputDispatchModeLw() {
5493 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5494 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07005495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496
5497 private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
Michael Chane96440f2009-05-06 10:27:36 -07005498 long curTime = SystemClock.uptimeMillis();
5499
Michael Chane10de972009-05-18 11:24:50 -07005500 if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
Michael Chane96440f2009-05-06 10:27:36 -07005501 if (mLastTouchEventType == eventType &&
5502 (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
5503 return;
5504 }
5505 mLastUserActivityCallTime = curTime;
5506 mLastTouchEventType = eventType;
5507 }
5508
5509 if (targetWin == null
5510 || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
5511 mPowerManager.userActivity(curTime, false, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512 }
5513 }
5514
5515 // tells if it's a cheek event or not -- this function is stateful
5516 private static final int EVENT_NONE = 0;
5517 private static final int EVENT_UNKNOWN = 0;
5518 private static final int EVENT_CHEEK = 0;
5519 private static final int EVENT_IGNORE_DURATION = 300; // ms
5520 private static final float CHEEK_THRESHOLD = 0.6f;
5521 private int mEventState = EVENT_NONE;
5522 private float mEventSize;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005524 private int eventType(MotionEvent ev) {
5525 float size = ev.getSize();
5526 switch (ev.getAction()) {
5527 case MotionEvent.ACTION_DOWN:
5528 mEventSize = size;
5529 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
5530 case MotionEvent.ACTION_UP:
5531 if (size > mEventSize) mEventSize = size;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005532 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 case MotionEvent.ACTION_MOVE:
5534 final int N = ev.getHistorySize();
5535 if (size > mEventSize) mEventSize = size;
5536 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5537 for (int i=0; i<N; i++) {
5538 size = ev.getHistoricalSize(i);
5539 if (size > mEventSize) mEventSize = size;
5540 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5541 }
5542 if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
5543 return TOUCH_EVENT;
5544 } else {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005545 return LONG_TOUCH_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005546 }
5547 default:
5548 // not good
5549 return OTHER_EVENT;
5550 }
5551 }
Jeff Brown349703e2010-06-22 01:27:15 -07005552
5553 private boolean mFatTouch; // remove me together with dispatchPointer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005554
5555 /**
5556 * @return Returns true if event was dispatched, false if it was dropped for any reason
5557 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005558 private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005559 if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 "dispatchPointer " + ev);
5561
Michael Chan53071d62009-05-13 17:29:48 -07005562 if (MEASURE_LATENCY) {
5563 lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
5564 }
5565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005567 ev, true, false, pid, uid);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005568
Michael Chan53071d62009-05-13 17:29:48 -07005569 if (MEASURE_LATENCY) {
5570 lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
5571 }
5572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 int action = ev.getAction();
Romain Guy06882f82009-06-10 13:36:04 -07005574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 if (action == MotionEvent.ACTION_UP) {
5576 // let go of our target
5577 mKeyWaiter.mMotionTarget = null;
5578 mPowerManager.logPointerUpEvent();
5579 } else if (action == MotionEvent.ACTION_DOWN) {
5580 mPowerManager.logPointerDownEvent();
5581 }
5582
5583 if (targetObj == null) {
5584 // In this case we are either dropping the event, or have received
5585 // a move or up without a down. It is common to receive move
5586 // events in such a way, since this means the user is moving the
5587 // pointer without actually pressing down. All other cases should
5588 // be atypical, so let's log them.
Michael Chane96440f2009-05-06 10:27:36 -07005589 if (action != MotionEvent.ACTION_MOVE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005590 Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 }
Dianne Hackborn6adba242009-11-10 11:10:09 -08005592 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005593 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 if (qev != null) {
5596 mQueue.recycleEvent(qev);
5597 }
5598 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005599 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005600 }
5601 if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005602 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005603 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 if (qev != null) {
5606 mQueue.recycleEvent(qev);
5607 }
5608 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005609 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005610 }
Romain Guy06882f82009-06-10 13:36:04 -07005611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 WindowState target = (WindowState)targetObj;
Romain Guy06882f82009-06-10 13:36:04 -07005613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005614 final long eventTime = ev.getEventTime();
Michael Chan53071d62009-05-13 17:29:48 -07005615 final long eventTimeNano = ev.getEventTimeNano();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005616
Joe Onorato8a9b2202010-02-26 18:56:32 -08005617 //Slog.i(TAG, "Sending " + ev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618
5619 if (uid != 0 && uid != target.mSession.mUid) {
5620 if (mContext.checkPermission(
5621 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5622 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005623 Slog.w(TAG, "Permission denied: injecting pointer event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 + pid + " uid " + uid + " to window " + target
5625 + " owned by uid " + target.mSession.mUid);
5626 if (qev != null) {
5627 mQueue.recycleEvent(qev);
5628 }
5629 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005630 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 }
5632 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005633
Michael Chan53071d62009-05-13 17:29:48 -07005634 if (MEASURE_LATENCY) {
5635 lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5636 }
5637
Romain Guy06882f82009-06-10 13:36:04 -07005638 if ((target.mAttrs.flags &
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5640 //target wants to ignore fat touch events
5641 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
5642 //explicit flag to return without processing event further
5643 boolean returnFlag = false;
5644 if((action == MotionEvent.ACTION_DOWN)) {
5645 mFatTouch = false;
5646 if(cheekPress) {
5647 mFatTouch = true;
5648 returnFlag = true;
5649 }
5650 } else {
5651 if(action == MotionEvent.ACTION_UP) {
5652 if(mFatTouch) {
5653 //earlier even was invalid doesnt matter if current up is cheekpress or not
5654 mFatTouch = false;
5655 returnFlag = true;
5656 } else if(cheekPress) {
5657 //cancel the earlier event
5658 ev.setAction(MotionEvent.ACTION_CANCEL);
5659 action = MotionEvent.ACTION_CANCEL;
5660 }
5661 } else if(action == MotionEvent.ACTION_MOVE) {
5662 if(mFatTouch) {
5663 //two cases here
5664 //an invalid down followed by 0 or moves(valid or invalid)
Romain Guy06882f82009-06-10 13:36:04 -07005665 //a valid down, invalid move, more moves. want to ignore till up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 returnFlag = true;
5667 } else if(cheekPress) {
5668 //valid down followed by invalid moves
5669 //an invalid move have to cancel earlier action
5670 ev.setAction(MotionEvent.ACTION_CANCEL);
5671 action = MotionEvent.ACTION_CANCEL;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 //note that the subsequent invalid moves will not get here
5674 mFatTouch = true;
5675 }
5676 }
5677 } //else if action
5678 if(returnFlag) {
5679 //recycle que, ev
5680 if (qev != null) {
5681 mQueue.recycleEvent(qev);
5682 }
5683 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005684 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 }
5686 } //end if target
Michael Chane96440f2009-05-06 10:27:36 -07005687
Michael Chan9f028e62009-08-04 17:37:46 -07005688 // Enable this for testing the "right" value
5689 if (false && action == MotionEvent.ACTION_DOWN) {
Michael Chane96440f2009-05-06 10:27:36 -07005690 int max_events_per_sec = 35;
5691 try {
5692 max_events_per_sec = Integer.parseInt(SystemProperties
5693 .get("windowsmgr.max_events_per_sec"));
5694 if (max_events_per_sec < 1) {
5695 max_events_per_sec = 35;
5696 }
5697 } catch (NumberFormatException e) {
5698 }
5699 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
5700 }
5701
5702 /*
5703 * Throttle events to minimize CPU usage when there's a flood of events
5704 * e.g. constant contact with the screen
5705 */
5706 if (action == MotionEvent.ACTION_MOVE) {
5707 long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
5708 long now = SystemClock.uptimeMillis();
5709 if (now < nextEventTime) {
5710 try {
5711 Thread.sleep(nextEventTime - now);
5712 } catch (InterruptedException e) {
5713 }
5714 mLastTouchEventTime = nextEventTime;
5715 } else {
5716 mLastTouchEventTime = now;
5717 }
5718 }
5719
Michael Chan53071d62009-05-13 17:29:48 -07005720 if (MEASURE_LATENCY) {
5721 lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5722 }
5723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 synchronized(mWindowMap) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005725 if (!target.isVisibleLw()) {
5726 // During this motion dispatch, the target window has become
5727 // invisible.
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005728 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005729 if (qev != null) {
5730 mQueue.recycleEvent(qev);
5731 }
5732 ev.recycle();
5733 return INJECT_SUCCEEDED;
5734 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 if (qev != null && action == MotionEvent.ACTION_MOVE) {
5737 mKeyWaiter.bindTargetWindowLocked(target,
5738 KeyWaiter.RETURN_PENDING_POINTER, qev);
5739 ev = null;
5740 } else {
5741 if (action == MotionEvent.ACTION_DOWN) {
5742 WindowState out = mKeyWaiter.mOutsideTouchTargets;
5743 if (out != null) {
5744 MotionEvent oev = MotionEvent.obtain(ev);
5745 oev.setAction(MotionEvent.ACTION_OUTSIDE);
5746 do {
5747 final Rect frame = out.mFrame;
5748 oev.offsetLocation(-(float)frame.left, -(float)frame.top);
5749 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005750 out.mClient.dispatchPointer(oev, eventTime, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005752 Slog.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 }
5754 oev.offsetLocation((float)frame.left, (float)frame.top);
5755 out = out.mNextOutsideTouch;
5756 } while (out != null);
5757 mKeyWaiter.mOutsideTouchTargets = null;
5758 }
5759 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005760
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005761 dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005762
Dianne Hackborn6adba242009-11-10 11:10:09 -08005763 final Rect frame = target.mFrame;
5764 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
5765 mKeyWaiter.bindTargetWindowLocked(target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766 }
5767 }
Romain Guy06882f82009-06-10 13:36:04 -07005768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005769 // finally offset the event to the target's coordinate system and
5770 // dispatch the event.
5771 try {
5772 if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005773 Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005775
Michael Chan53071d62009-05-13 17:29:48 -07005776 if (MEASURE_LATENCY) {
5777 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
5778 }
5779
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005780 target.mClient.dispatchPointer(ev, eventTime, true);
Michael Chan53071d62009-05-13 17:29:48 -07005781
5782 if (MEASURE_LATENCY) {
5783 lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
5784 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005785 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005786 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005787 Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 mKeyWaiter.mMotionTarget = null;
5789 try {
5790 removeWindow(target.mSession, target.mClient);
5791 } catch (java.util.NoSuchElementException ex) {
5792 // This will happen if the window has already been
5793 // removed.
5794 }
5795 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005796 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 }
Romain Guy06882f82009-06-10 13:36:04 -07005798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 /**
5800 * @return Returns true if event was dispatched, false if it was dropped for any reason
5801 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005802 private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005803 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
Romain Guy06882f82009-06-10 13:36:04 -07005805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005807 ev, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005809 Slog.w(TAG, "No focus window, dropping trackball: " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 if (qev != null) {
5811 mQueue.recycleEvent(qev);
5812 }
5813 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005814 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 }
5816 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
5817 if (qev != null) {
5818 mQueue.recycleEvent(qev);
5819 }
5820 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005821 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005822 }
Romain Guy06882f82009-06-10 13:36:04 -07005823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005824 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005826 if (uid != 0 && uid != focus.mSession.mUid) {
5827 if (mContext.checkPermission(
5828 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5829 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005830 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 + pid + " uid " + uid + " to window " + focus
5832 + " owned by uid " + focus.mSession.mUid);
5833 if (qev != null) {
5834 mQueue.recycleEvent(qev);
5835 }
5836 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005837 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005838 }
5839 }
Romain Guy06882f82009-06-10 13:36:04 -07005840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 final long eventTime = ev.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005843 synchronized(mWindowMap) {
5844 if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
5845 mKeyWaiter.bindTargetWindowLocked(focus,
5846 KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
5847 // We don't deliver movement events to the client, we hold
5848 // them and wait for them to call back.
5849 ev = null;
5850 } else {
5851 mKeyWaiter.bindTargetWindowLocked(focus);
5852 }
5853 }
Romain Guy06882f82009-06-10 13:36:04 -07005854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005855 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005856 focus.mClient.dispatchTrackball(ev, eventTime, true);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005857 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005858 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005859 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 try {
5861 removeWindow(focus.mSession, focus.mClient);
5862 } catch (java.util.NoSuchElementException ex) {
5863 // This will happen if the window has already been
5864 // removed.
5865 }
5866 }
Romain Guy06882f82009-06-10 13:36:04 -07005867
Dianne Hackborncfaef692009-06-15 14:24:44 -07005868 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
Romain Guy06882f82009-06-10 13:36:04 -07005870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005871 /**
5872 * @return Returns true if event was dispatched, false if it was dropped for any reason
5873 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005874 private int dispatchKey(KeyEvent event, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005875 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876
5877 Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005878 null, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005879 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005880 Slog.w(TAG, "No focus window, dropping: " + event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005881 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 }
5883 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005884 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 }
Romain Guy06882f82009-06-10 13:36:04 -07005886
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07005887 // Okay we have finished waiting for the last event to be processed.
5888 // First off, if this is a repeat event, check to see if there is
5889 // a corresponding up event in the queue. If there is, we will
5890 // just drop the repeat, because it makes no sense to repeat after
5891 // the user has released a key. (This is especially important for
5892 // long presses.)
5893 if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
5894 return INJECT_SUCCEEDED;
5895 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005898
Joe Onorato8a9b2202010-02-26 18:56:32 -08005899 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 TAG, "Dispatching to " + focus + ": " + event);
5901
5902 if (uid != 0 && uid != focus.mSession.mUid) {
5903 if (mContext.checkPermission(
5904 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5905 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005906 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 + pid + " uid " + uid + " to window " + focus
5908 + " owned by uid " + focus.mSession.mUid);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005909 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 }
5911 }
Romain Guy06882f82009-06-10 13:36:04 -07005912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005913 synchronized(mWindowMap) {
5914 mKeyWaiter.bindTargetWindowLocked(focus);
5915 }
5916
5917 // NOSHIP extra state logging
5918 mKeyWaiter.recordDispatchState(event, focus);
5919 // END NOSHIP
Romain Guy06882f82009-06-10 13:36:04 -07005920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 try {
5922 if (DEBUG_INPUT || DEBUG_FOCUS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005923 Slog.v(TAG, "Delivering key " + event.getKeyCode()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 + " to " + focus);
5925 }
5926 focus.mClient.dispatchKey(event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005927 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005928 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005929 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005930 try {
5931 removeWindow(focus.mSession, focus.mClient);
5932 } catch (java.util.NoSuchElementException ex) {
5933 // This will happen if the window has already been
5934 // removed.
5935 }
5936 }
Romain Guy06882f82009-06-10 13:36:04 -07005937
Dianne Hackborncfaef692009-06-15 14:24:44 -07005938 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 }
Romain Guy06882f82009-06-10 13:36:04 -07005940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 public void pauseKeyDispatching(IBinder _token) {
5942 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5943 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005944 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 }
5946
5947 synchronized (mWindowMap) {
5948 WindowToken token = mTokenMap.get(_token);
5949 if (token != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005950 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5951 mInputMonitor.pauseDispatchingLw(token);
5952 } else {
5953 mKeyWaiter.pauseDispatchingLocked(token);
5954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 }
5956 }
5957 }
5958
5959 public void resumeKeyDispatching(IBinder _token) {
5960 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5961 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005962 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963 }
5964
5965 synchronized (mWindowMap) {
5966 WindowToken token = mTokenMap.get(_token);
5967 if (token != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005968 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5969 mInputMonitor.resumeDispatchingLw(token);
5970 } else {
5971 mKeyWaiter.resumeDispatchingLocked(token);
5972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 }
5974 }
5975 }
5976
5977 public void setEventDispatching(boolean enabled) {
5978 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5979 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005980 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005981 }
5982
5983 synchronized (mWindowMap) {
Jeff Brown349703e2010-06-22 01:27:15 -07005984 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5985 mInputMonitor.setEventDispatchingLw(enabled);
5986 } else {
5987 mKeyWaiter.setEventDispatchingLocked(enabled);
5988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005989 }
5990 }
Romain Guy06882f82009-06-10 13:36:04 -07005991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005992 /**
5993 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005994 *
5995 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 * {@link SystemClock#uptimeMillis()} as the timebase.)
5997 * @param sync If true, wait for the event to be completed before returning to the caller.
5998 * @return Returns true if event was dispatched, false if it was dropped for any reason
5999 */
6000 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6001 long downTime = ev.getDownTime();
6002 long eventTime = ev.getEventTime();
6003
6004 int action = ev.getAction();
6005 int code = ev.getKeyCode();
6006 int repeatCount = ev.getRepeatCount();
6007 int metaState = ev.getMetaState();
6008 int deviceId = ev.getDeviceId();
6009 int scancode = ev.getScanCode();
6010
6011 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6012 if (downTime == 0) downTime = eventTime;
6013
6014 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07006015 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006017 final int pid = Binder.getCallingPid();
6018 final int uid = Binder.getCallingUid();
6019 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006020
6021 final int result;
6022 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006023 result = mInputManager.injectKeyEvent(newEvent, InputQueue.INPUT_EVENT_NATURE_KEY,
6024 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006025 } else {
6026 result = dispatchKey(newEvent, pid, uid);
6027 if (sync) {
6028 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07006031
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006032 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006033 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006034 }
6035
6036 /**
6037 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07006038 *
6039 * @param ev A motion event describing the pointer (touch) action. (As noted in
6040 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 * {@link SystemClock#uptimeMillis()} as the timebase.)
6042 * @param sync If true, wait for the event to be completed before returning to the caller.
6043 * @return Returns true if event was dispatched, false if it was dropped for any reason
6044 */
6045 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006046 final int pid = Binder.getCallingPid();
6047 final int uid = Binder.getCallingUid();
6048 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006049
6050 final int result;
6051 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006052 result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TOUCH,
6053 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006054 } else {
6055 result = dispatchPointer(null, ev, pid, uid);
6056 if (sync) {
6057 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006059 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07006060
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006061 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006062 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006063 }
Romain Guy06882f82009-06-10 13:36:04 -07006064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006065 /**
6066 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07006067 *
6068 * @param ev A motion event describing the trackball action. (As noted in
6069 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 * {@link SystemClock#uptimeMillis()} as the timebase.)
6071 * @param sync If true, wait for the event to be completed before returning to the caller.
6072 * @return Returns true if event was dispatched, false if it was dropped for any reason
6073 */
6074 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006075 final int pid = Binder.getCallingPid();
6076 final int uid = Binder.getCallingUid();
6077 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006078
6079 final int result;
6080 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006081 result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TRACKBALL,
6082 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006083 } else {
6084 result = dispatchTrackball(null, ev, pid, uid);
6085 if (sync) {
6086 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07006089
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006090 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006091 return reportInjectionResult(result);
6092 }
6093
6094 private boolean reportInjectionResult(int result) {
6095 if (ENABLE_NATIVE_INPUT_DISPATCH) {
6096 switch (result) {
6097 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6098 Slog.w(TAG, "Input event injection permission denied.");
6099 throw new SecurityException(
6100 "Injecting to another application requires INJECT_EVENTS permission");
6101 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
6102 Slog.v(TAG, "Input event injection succeeded.");
6103 return true;
6104 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6105 Slog.w(TAG, "Input event injection timed out.");
6106 return false;
6107 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6108 default:
6109 Slog.w(TAG, "Input event injection failed.");
6110 return false;
6111 }
6112 } else {
6113 switch (result) {
6114 case INJECT_NO_PERMISSION:
6115 throw new SecurityException(
6116 "Injecting to another application requires INJECT_EVENTS permission");
6117 case INJECT_SUCCEEDED:
6118 return true;
6119 }
6120 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006122 }
Romain Guy06882f82009-06-10 13:36:04 -07006123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 private WindowState getFocusedWindow() {
6125 synchronized (mWindowMap) {
6126 return getFocusedWindowLocked();
6127 }
6128 }
6129
6130 private WindowState getFocusedWindowLocked() {
6131 return mCurrentFocus;
6132 }
Romain Guy06882f82009-06-10 13:36:04 -07006133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006134 /**
6135 * This class holds the state for dispatching key events. This state
6136 * is protected by the KeyWaiter instance, NOT by the window lock. You
6137 * can be holding the main window lock while acquire the KeyWaiter lock,
6138 * but not the other way around.
6139 */
6140 final class KeyWaiter {
6141 // NOSHIP debugging
6142 public class DispatchState {
6143 private KeyEvent event;
6144 private WindowState focus;
6145 private long time;
6146 private WindowState lastWin;
6147 private IBinder lastBinder;
6148 private boolean finished;
6149 private boolean gotFirstWindow;
6150 private boolean eventDispatching;
6151 private long timeToSwitch;
6152 private boolean wasFrozen;
6153 private boolean focusPaused;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006154 private WindowState curFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006156 DispatchState(KeyEvent theEvent, WindowState theFocus) {
6157 focus = theFocus;
6158 event = theEvent;
6159 time = System.currentTimeMillis();
6160 // snapshot KeyWaiter state
6161 lastWin = mLastWin;
6162 lastBinder = mLastBinder;
6163 finished = mFinished;
6164 gotFirstWindow = mGotFirstWindow;
6165 eventDispatching = mEventDispatching;
6166 timeToSwitch = mTimeToSwitch;
6167 wasFrozen = mWasFrozen;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006168 curFocus = mCurrentFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 // cache the paused state at ctor time as well
6170 if (theFocus == null || theFocus.mToken == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 focusPaused = false;
6172 } else {
6173 focusPaused = theFocus.mToken.paused;
6174 }
6175 }
Romain Guy06882f82009-06-10 13:36:04 -07006176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 public String toString() {
6178 return "{{" + event + " to " + focus + " @ " + time
6179 + " lw=" + lastWin + " lb=" + lastBinder
6180 + " fin=" + finished + " gfw=" + gotFirstWindow
6181 + " ed=" + eventDispatching + " tts=" + timeToSwitch
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006182 + " wf=" + wasFrozen + " fp=" + focusPaused
Christopher Tate46d45252010-02-09 15:48:57 -08006183 + " mcf=" + curFocus + "}}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006184 }
6185 };
6186 private DispatchState mDispatchState = null;
6187 public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
6188 mDispatchState = new DispatchState(theEvent, theFocus);
6189 }
6190 // END NOSHIP
6191
6192 public static final int RETURN_NOTHING = 0;
6193 public static final int RETURN_PENDING_POINTER = 1;
6194 public static final int RETURN_PENDING_TRACKBALL = 2;
Romain Guy06882f82009-06-10 13:36:04 -07006195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 final Object SKIP_TARGET_TOKEN = new Object();
6197 final Object CONSUMED_EVENT_TOKEN = new Object();
Romain Guy06882f82009-06-10 13:36:04 -07006198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006199 private WindowState mLastWin = null;
6200 private IBinder mLastBinder = null;
6201 private boolean mFinished = true;
6202 private boolean mGotFirstWindow = false;
6203 private boolean mEventDispatching = true;
6204 private long mTimeToSwitch = 0;
6205 /* package */ boolean mWasFrozen = false;
Romain Guy06882f82009-06-10 13:36:04 -07006206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006207 // Target of Motion events
6208 WindowState mMotionTarget;
Romain Guy06882f82009-06-10 13:36:04 -07006209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006210 // Windows above the target who would like to receive an "outside"
6211 // touch event for any down events outside of them.
6212 WindowState mOutsideTouchTargets;
6213
6214 /**
6215 * Wait for the last event dispatch to complete, then find the next
6216 * target that should receive the given event and wait for that one
6217 * to be ready to receive it.
6218 */
6219 Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
6220 MotionEvent nextMotion, boolean isPointerEvent,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006221 boolean failIfTimeout, int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006222 long startTime = SystemClock.uptimeMillis();
6223 long keyDispatchingTimeout = 5 * 1000;
6224 long waitedFor = 0;
6225
6226 while (true) {
6227 // Figure out which window we care about. It is either the
6228 // last window we are waiting to have process the event or,
6229 // if none, then the next window we think the event should go
6230 // to. Note: we retrieve mLastWin outside of the lock, so
6231 // it may change before we lock. Thus we must check it again.
6232 WindowState targetWin = mLastWin;
6233 boolean targetIsNew = targetWin == null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006234 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 TAG, "waitForLastKey: mFinished=" + mFinished +
6236 ", mLastWin=" + mLastWin);
6237 if (targetIsNew) {
6238 Object target = findTargetWindow(nextKey, qev, nextMotion,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006239 isPointerEvent, callingPid, callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 if (target == SKIP_TARGET_TOKEN) {
6241 // The user has pressed a special key, and we are
6242 // dropping all pending events before it.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006243 if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 + " " + nextMotion);
6245 return null;
6246 }
6247 if (target == CONSUMED_EVENT_TOKEN) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006248 if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 + " " + nextMotion);
6250 return target;
6251 }
6252 targetWin = (WindowState)target;
6253 }
Romain Guy06882f82009-06-10 13:36:04 -07006254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 AppWindowToken targetApp = null;
Romain Guy06882f82009-06-10 13:36:04 -07006256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006257 // Now: is it okay to send the next event to this window?
6258 synchronized (this) {
6259 // First: did we come here based on the last window not
6260 // being null, but it changed by the time we got here?
6261 // If so, try again.
6262 if (!targetIsNew && mLastWin == null) {
6263 continue;
6264 }
Romain Guy06882f82009-06-10 13:36:04 -07006265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006266 // We never dispatch events if not finished with the
6267 // last one, or the display is frozen.
6268 if (mFinished && !mDisplayFrozen) {
6269 // If event dispatching is disabled, then we
6270 // just consume the events.
6271 if (!mEventDispatching) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006272 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 "Skipping event; dispatching disabled: "
6274 + nextKey + " " + nextMotion);
6275 return null;
6276 }
6277 if (targetWin != null) {
6278 // If this is a new target, and that target is not
6279 // paused or unresponsive, then all looks good to
6280 // handle the event.
6281 if (targetIsNew && !targetWin.mToken.paused) {
6282 return targetWin;
6283 }
Romain Guy06882f82009-06-10 13:36:04 -07006284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006285 // If we didn't find a target window, and there is no
6286 // focused app window, then just eat the events.
6287 } else if (mFocusedApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006288 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 "Skipping event; no focused app: "
6290 + nextKey + " " + nextMotion);
6291 return null;
6292 }
6293 }
Romain Guy06882f82009-06-10 13:36:04 -07006294
Joe Onorato8a9b2202010-02-26 18:56:32 -08006295 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 TAG, "Waiting for last key in " + mLastBinder
6297 + " target=" + targetWin
6298 + " mFinished=" + mFinished
6299 + " mDisplayFrozen=" + mDisplayFrozen
6300 + " targetIsNew=" + targetIsNew
6301 + " paused="
6302 + (targetWin != null ? targetWin.mToken.paused : false)
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006303 + " mFocusedApp=" + mFocusedApp
6304 + " mCurrentFocus=" + mCurrentFocus);
Romain Guy06882f82009-06-10 13:36:04 -07006305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 targetApp = targetWin != null
6307 ? targetWin.mAppToken : mFocusedApp;
Romain Guy06882f82009-06-10 13:36:04 -07006308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 long curTimeout = keyDispatchingTimeout;
6310 if (mTimeToSwitch != 0) {
6311 long now = SystemClock.uptimeMillis();
6312 if (mTimeToSwitch <= now) {
6313 // If an app switch key has been pressed, and we have
6314 // waited too long for the current app to finish
6315 // processing keys, then wait no more!
Christopher Tate136b1f92010-02-11 17:51:24 -08006316 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 continue;
6318 }
6319 long switchTimeout = mTimeToSwitch - now;
6320 if (curTimeout > switchTimeout) {
6321 curTimeout = switchTimeout;
6322 }
6323 }
Romain Guy06882f82009-06-10 13:36:04 -07006324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 try {
6326 // after that continue
6327 // processing keys, so we don't get stuck.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006328 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 TAG, "Waiting for key dispatch: " + curTimeout);
6330 wait(curTimeout);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006331 if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 + SystemClock.uptimeMillis() + " startTime="
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006333 + startTime + " switchTime=" + mTimeToSwitch
6334 + " target=" + targetWin + " mLW=" + mLastWin
6335 + " mLB=" + mLastBinder + " fin=" + mFinished
6336 + " mCurrentFocus=" + mCurrentFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 } catch (InterruptedException e) {
6338 }
6339 }
6340
6341 // If we were frozen during configuration change, restart the
6342 // timeout checks from now; otherwise look at whether we timed
6343 // out before awakening.
6344 if (mWasFrozen) {
6345 waitedFor = 0;
6346 mWasFrozen = false;
6347 } else {
6348 waitedFor = SystemClock.uptimeMillis() - startTime;
6349 }
6350
6351 if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
6352 IApplicationToken at = null;
6353 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006354 Slog.w(TAG, "Key dispatching timed out sending to " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 (targetWin != null ? targetWin.mAttrs.getTitle()
Ken Shirriff8200b202010-02-04 13:34:37 -08006356 : "<null>: no window ready for key dispatch"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006357 // NOSHIP debugging
Joe Onorato8a9b2202010-02-26 18:56:32 -08006358 Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
6359 Slog.w(TAG, "Current dispatch state: " +
Ken Shirriff8200b202010-02-04 13:34:37 -08006360 new DispatchState(nextKey, targetWin));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361 // END NOSHIP
6362 //dump();
6363 if (targetWin != null) {
6364 at = targetWin.getAppToken();
6365 } else if (targetApp != null) {
6366 at = targetApp.appToken;
6367 }
6368 }
6369
6370 boolean abort = true;
6371 if (at != null) {
6372 try {
6373 long timeout = at.getKeyDispatchingTimeout();
6374 if (timeout > waitedFor) {
6375 // we did not wait the proper amount of time for this application.
6376 // set the timeout to be the real timeout and wait again.
6377 keyDispatchingTimeout = timeout - waitedFor;
6378 continue;
6379 } else {
6380 abort = at.keyDispatchingTimedOut();
6381 }
6382 } catch (RemoteException ex) {
6383 }
6384 }
6385
6386 synchronized (this) {
6387 if (abort && (mLastWin == targetWin || targetWin == null)) {
6388 mFinished = true;
Romain Guy06882f82009-06-10 13:36:04 -07006389 if (mLastWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006390 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 "Window " + mLastWin +
6392 " timed out on key input");
6393 if (mLastWin.mToken.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006394 Slog.w(TAG, "Un-pausing dispatching to this window");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 mLastWin.mToken.paused = false;
6396 }
6397 }
6398 if (mMotionTarget == targetWin) {
6399 mMotionTarget = null;
6400 }
6401 mLastWin = null;
6402 mLastBinder = null;
6403 if (failIfTimeout || targetWin == null) {
6404 return null;
6405 }
6406 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006407 Slog.w(TAG, "Continuing to wait for key to be dispatched");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006408 startTime = SystemClock.uptimeMillis();
6409 }
6410 }
6411 }
6412 }
6413 }
Romain Guy06882f82009-06-10 13:36:04 -07006414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006415 Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006416 MotionEvent nextMotion, boolean isPointerEvent,
6417 int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006418 mOutsideTouchTargets = null;
Romain Guy06882f82009-06-10 13:36:04 -07006419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 if (nextKey != null) {
6421 // Find the target window for a normal key event.
6422 final int keycode = nextKey.getKeyCode();
6423 final int repeatCount = nextKey.getRepeatCount();
6424 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
6425 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006427 if (!dispatch) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006428 if (callingUid == 0 ||
6429 mContext.checkPermission(
6430 android.Manifest.permission.INJECT_EVENTS,
6431 callingPid, callingUid)
6432 == PackageManager.PERMISSION_GRANTED) {
6433 mPolicy.interceptKeyTi(null, keycode,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006434 nextKey.getMetaState(), down, repeatCount,
6435 nextKey.getFlags());
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006436 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006437 Slog.w(TAG, "Event timeout during app switch: dropping "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 + nextKey);
6439 return SKIP_TARGET_TOKEN;
6440 }
Romain Guy06882f82009-06-10 13:36:04 -07006441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006442 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
Romain Guy06882f82009-06-10 13:36:04 -07006443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006444 WindowState focus = null;
6445 synchronized(mWindowMap) {
6446 focus = getFocusedWindowLocked();
6447 }
Romain Guy06882f82009-06-10 13:36:04 -07006448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
Romain Guy06882f82009-06-10 13:36:04 -07006450
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006451 if (callingUid == 0 ||
6452 (focus != null && callingUid == focus.mSession.mUid) ||
6453 mContext.checkPermission(
6454 android.Manifest.permission.INJECT_EVENTS,
6455 callingPid, callingUid)
6456 == PackageManager.PERMISSION_GRANTED) {
6457 if (mPolicy.interceptKeyTi(focus,
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006458 keycode, nextKey.getMetaState(), down, repeatCount,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006459 nextKey.getFlags())) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006460 return CONSUMED_EVENT_TOKEN;
6461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 }
Romain Guy06882f82009-06-10 13:36:04 -07006463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006464 return focus;
Romain Guy06882f82009-06-10 13:36:04 -07006465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006466 } else if (!isPointerEvent) {
6467 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
6468 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006469 Slog.w(TAG, "Event timeout during app switch: dropping trackball "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 + nextMotion);
6471 return SKIP_TARGET_TOKEN;
6472 }
Romain Guy06882f82009-06-10 13:36:04 -07006473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 WindowState focus = null;
6475 synchronized(mWindowMap) {
6476 focus = getFocusedWindowLocked();
6477 }
Romain Guy06882f82009-06-10 13:36:04 -07006478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
6480 return focus;
6481 }
Romain Guy06882f82009-06-10 13:36:04 -07006482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006483 if (nextMotion == null) {
6484 return SKIP_TARGET_TOKEN;
6485 }
Romain Guy06882f82009-06-10 13:36:04 -07006486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
6488 KeyEvent.KEYCODE_UNKNOWN);
6489 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006490 Slog.w(TAG, "Event timeout during app switch: dropping pointer "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491 + nextMotion);
6492 return SKIP_TARGET_TOKEN;
6493 }
Romain Guy06882f82009-06-10 13:36:04 -07006494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006495 // Find the target window for a pointer event.
6496 int action = nextMotion.getAction();
6497 final float xf = nextMotion.getX();
6498 final float yf = nextMotion.getY();
6499 final long eventTime = nextMotion.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07006500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 final boolean screenWasOff = qev != null
6502 && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07006503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006504 WindowState target = null;
Romain Guy06882f82009-06-10 13:36:04 -07006505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 synchronized(mWindowMap) {
6507 synchronized (this) {
6508 if (action == MotionEvent.ACTION_DOWN) {
6509 if (mMotionTarget != null) {
6510 // this is weird, we got a pen down, but we thought it was
6511 // already down!
6512 // XXX: We should probably send an ACTION_UP to the current
6513 // target.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006514 Slog.w(TAG, "Pointer down received while already down in: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 + mMotionTarget);
6516 mMotionTarget = null;
6517 }
Romain Guy06882f82009-06-10 13:36:04 -07006518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 // ACTION_DOWN is special, because we need to lock next events to
6520 // the window we'll land onto.
6521 final int x = (int)xf;
6522 final int y = (int)yf;
Romain Guy06882f82009-06-10 13:36:04 -07006523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006524 final ArrayList windows = mWindows;
6525 final int N = windows.size();
6526 WindowState topErrWindow = null;
6527 final Rect tmpRect = mTempRect;
6528 for (int i=N-1; i>=0; i--) {
6529 WindowState child = (WindowState)windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006530 //Slog.i(TAG, "Checking dispatch to: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 final int flags = child.mAttrs.flags;
6532 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
6533 if (topErrWindow == null) {
6534 topErrWindow = child;
6535 }
6536 }
6537 if (!child.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006538 //Slog.i(TAG, "Not visible!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006539 continue;
6540 }
6541 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006542 //Slog.i(TAG, "Not touchable!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006543 if ((flags & WindowManager.LayoutParams
6544 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6545 child.mNextOutsideTouch = mOutsideTouchTargets;
6546 mOutsideTouchTargets = child;
6547 }
6548 continue;
6549 }
6550 tmpRect.set(child.mFrame);
6551 if (child.mTouchableInsets == ViewTreeObserver
6552 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
6553 // The touch is inside of the window if it is
6554 // inside the frame, AND the content part of that
6555 // frame that was given by the application.
6556 tmpRect.left += child.mGivenContentInsets.left;
6557 tmpRect.top += child.mGivenContentInsets.top;
6558 tmpRect.right -= child.mGivenContentInsets.right;
6559 tmpRect.bottom -= child.mGivenContentInsets.bottom;
6560 } else if (child.mTouchableInsets == ViewTreeObserver
6561 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
6562 // The touch is inside of the window if it is
6563 // inside the frame, AND the visible part of that
6564 // frame that was given by the application.
6565 tmpRect.left += child.mGivenVisibleInsets.left;
6566 tmpRect.top += child.mGivenVisibleInsets.top;
6567 tmpRect.right -= child.mGivenVisibleInsets.right;
6568 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
6569 }
6570 final int touchFlags = flags &
6571 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6572 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
6573 if (tmpRect.contains(x, y) || touchFlags == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006574 //Slog.i(TAG, "Using this target!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006575 if (!screenWasOff || (flags &
6576 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
6577 mMotionTarget = child;
6578 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006579 //Slog.i(TAG, "Waking, skip!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 mMotionTarget = null;
6581 }
6582 break;
6583 }
Romain Guy06882f82009-06-10 13:36:04 -07006584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006585 if ((flags & WindowManager.LayoutParams
6586 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6587 child.mNextOutsideTouch = mOutsideTouchTargets;
6588 mOutsideTouchTargets = child;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006589 //Slog.i(TAG, "Adding to outside target list: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 }
6591 }
6592
6593 // if there's an error window but it's not accepting
6594 // focus (typically because it is not yet visible) just
6595 // wait for it -- any other focused window may in fact
6596 // be in ANR state.
6597 if (topErrWindow != null && mMotionTarget != topErrWindow) {
6598 mMotionTarget = null;
6599 }
6600 }
Romain Guy06882f82009-06-10 13:36:04 -07006601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 target = mMotionTarget;
6603 }
6604 }
Romain Guy06882f82009-06-10 13:36:04 -07006605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006606 wakeupIfNeeded(target, eventType(nextMotion));
Romain Guy06882f82009-06-10 13:36:04 -07006607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006608 // Pointer events are a little different -- if there isn't a
6609 // target found for any event, then just drop it.
6610 return target != null ? target : SKIP_TARGET_TOKEN;
6611 }
Romain Guy06882f82009-06-10 13:36:04 -07006612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 boolean checkShouldDispatchKey(int keycode) {
6614 synchronized (this) {
6615 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
6616 mTimeToSwitch = 0;
6617 return true;
6618 }
6619 if (mTimeToSwitch != 0
6620 && mTimeToSwitch < SystemClock.uptimeMillis()) {
6621 return false;
6622 }
6623 return true;
6624 }
6625 }
Romain Guy06882f82009-06-10 13:36:04 -07006626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 void bindTargetWindowLocked(WindowState win,
6628 int pendingWhat, QueuedEvent pendingMotion) {
6629 synchronized (this) {
6630 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
6631 }
6632 }
Romain Guy06882f82009-06-10 13:36:04 -07006633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 void bindTargetWindowLocked(WindowState win) {
6635 synchronized (this) {
6636 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
6637 }
6638 }
6639
6640 void bindTargetWindowLockedLocked(WindowState win,
6641 int pendingWhat, QueuedEvent pendingMotion) {
6642 mLastWin = win;
6643 mLastBinder = win.mClient.asBinder();
6644 mFinished = false;
6645 if (pendingMotion != null) {
6646 final Session s = win.mSession;
6647 if (pendingWhat == RETURN_PENDING_POINTER) {
6648 releasePendingPointerLocked(s);
6649 s.mPendingPointerMove = pendingMotion;
6650 s.mPendingPointerWindow = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006651 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006652 "bindTargetToWindow " + s.mPendingPointerMove);
6653 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
6654 releasePendingTrackballLocked(s);
6655 s.mPendingTrackballMove = pendingMotion;
6656 s.mPendingTrackballWindow = win;
6657 }
6658 }
6659 }
Romain Guy06882f82009-06-10 13:36:04 -07006660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 void releasePendingPointerLocked(Session s) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006662 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 "releasePendingPointer " + s.mPendingPointerMove);
6664 if (s.mPendingPointerMove != null) {
6665 mQueue.recycleEvent(s.mPendingPointerMove);
6666 s.mPendingPointerMove = null;
6667 }
6668 }
Romain Guy06882f82009-06-10 13:36:04 -07006669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006670 void releasePendingTrackballLocked(Session s) {
6671 if (s.mPendingTrackballMove != null) {
6672 mQueue.recycleEvent(s.mPendingTrackballMove);
6673 s.mPendingTrackballMove = null;
6674 }
6675 }
Romain Guy06882f82009-06-10 13:36:04 -07006676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006677 MotionEvent finishedKey(Session session, IWindow client, boolean force,
6678 int returnWhat) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006679 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006680 TAG, "finishedKey: client=" + client + ", force=" + force);
6681
6682 if (client == null) {
6683 return null;
6684 }
6685
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006686 MotionEvent res = null;
6687 QueuedEvent qev = null;
6688 WindowState win = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006691 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 TAG, "finishedKey: client=" + client.asBinder()
6693 + ", force=" + force + ", last=" + mLastBinder
6694 + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
6695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006696 if (returnWhat == RETURN_PENDING_POINTER) {
6697 qev = session.mPendingPointerMove;
6698 win = session.mPendingPointerWindow;
6699 session.mPendingPointerMove = null;
6700 session.mPendingPointerWindow = null;
6701 } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
6702 qev = session.mPendingTrackballMove;
6703 win = session.mPendingTrackballWindow;
6704 session.mPendingTrackballMove = null;
6705 session.mPendingTrackballWindow = null;
6706 }
Romain Guy06882f82009-06-10 13:36:04 -07006707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 if (mLastBinder == client.asBinder()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006709 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006710 TAG, "finishedKey: last paused="
6711 + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
6712 if (mLastWin != null && (!mLastWin.mToken.paused || force
6713 || !mEventDispatching)) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006714 doFinishedKeyLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 } else {
6716 // Make sure to wake up anyone currently waiting to
6717 // dispatch a key, so they can re-evaluate their
6718 // current situation.
6719 mFinished = true;
6720 notifyAll();
6721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006722 }
Romain Guy06882f82009-06-10 13:36:04 -07006723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 if (qev != null) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006725 res = (MotionEvent)qev.event;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006726 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 "Returning pending motion: " + res);
6728 mQueue.recycleEvent(qev);
6729 if (win != null && returnWhat == RETURN_PENDING_POINTER) {
6730 res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
6731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 }
Christopher Tate2624fbc2009-12-11 12:11:31 -08006733 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006734
Christopher Tate2624fbc2009-12-11 12:11:31 -08006735 if (res != null && returnWhat == RETURN_PENDING_POINTER) {
6736 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08006737 dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006738 }
6739 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006740
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006741 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 }
6743
6744 void tickle() {
6745 synchronized (this) {
6746 notifyAll();
6747 }
6748 }
Romain Guy06882f82009-06-10 13:36:04 -07006749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750 void handleNewWindowLocked(WindowState newWindow) {
6751 if (!newWindow.canReceiveKeys()) {
6752 return;
6753 }
6754 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006755 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756 TAG, "New key dispatch window: win="
6757 + newWindow.mClient.asBinder()
6758 + ", last=" + mLastBinder
6759 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6760 + "), finished=" + mFinished + ", paused="
6761 + newWindow.mToken.paused);
6762
6763 // Displaying a window implicitly causes dispatching to
6764 // be unpaused. (This is to protect against bugs if someone
6765 // pauses dispatching but forgets to resume.)
6766 newWindow.mToken.paused = false;
6767
6768 mGotFirstWindow = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769
6770 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006771 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 "New SYSTEM_ERROR window; resetting state");
6773 mLastWin = null;
6774 mLastBinder = null;
6775 mMotionTarget = null;
6776 mFinished = true;
6777 } else if (mLastWin != null) {
6778 // If the new window is above the window we are
6779 // waiting on, then stop waiting and let key dispatching
6780 // start on the new guy.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006781 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006782 TAG, "Last win layer=" + mLastWin.mLayer
6783 + ", new win layer=" + newWindow.mLayer);
6784 if (newWindow.mLayer >= mLastWin.mLayer) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006785 // The new window is above the old; finish pending input to the last
6786 // window and start directing it to the new one.
6787 mLastWin.mToken.paused = false;
Christopher Tate136b1f92010-02-11 17:51:24 -08006788 doFinishedKeyLocked(false); // does a notifyAll()
6789 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 }
6791 }
6792
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006793 // Now that we've put a new window state in place, make the event waiter
6794 // take notice and retarget its attentions.
6795 notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 }
6797 }
6798
6799 void pauseDispatchingLocked(WindowToken token) {
6800 synchronized (this)
6801 {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006802 if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 token.paused = true;
6804
6805 /*
6806 if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
6807 mPaused = true;
6808 } else {
6809 if (mLastWin == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006810 Slog.i(TAG, "Key dispatching not paused: no last window.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 } else if (mFinished) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006812 Slog.i(TAG, "Key dispatching not paused: finished last key.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006814 Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 }
6816 }
6817 */
6818 }
6819 }
6820
6821 void resumeDispatchingLocked(WindowToken token) {
6822 synchronized (this) {
6823 if (token.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006824 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 TAG, "Resuming WindowToken " + token
6826 + ", last=" + mLastBinder
6827 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6828 + "), finished=" + mFinished + ", paused="
6829 + token.paused);
6830 token.paused = false;
6831 if (mLastWin != null && mLastWin.mToken == token && mFinished) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006832 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 } else {
6834 notifyAll();
6835 }
6836 }
6837 }
6838 }
6839
6840 void setEventDispatchingLocked(boolean enabled) {
6841 synchronized (this) {
6842 mEventDispatching = enabled;
6843 notifyAll();
6844 }
6845 }
Romain Guy06882f82009-06-10 13:36:04 -07006846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 void appSwitchComing() {
6848 synchronized (this) {
6849 // Don't wait for more than .5 seconds for app to finish
6850 // processing the pending events.
6851 long now = SystemClock.uptimeMillis() + 500;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006852 if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
6854 mTimeToSwitch = now;
6855 }
6856 notifyAll();
6857 }
6858 }
Romain Guy06882f82009-06-10 13:36:04 -07006859
Christopher Tate136b1f92010-02-11 17:51:24 -08006860 private final void doFinishedKeyLocked(boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 if (mLastWin != null) {
6862 releasePendingPointerLocked(mLastWin.mSession);
6863 releasePendingTrackballLocked(mLastWin.mSession);
6864 }
Romain Guy06882f82009-06-10 13:36:04 -07006865
Christopher Tate136b1f92010-02-11 17:51:24 -08006866 if (force || mLastWin == null || !mLastWin.mToken.paused
6867 || !mLastWin.isVisibleLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 // If the current window has been paused, we aren't -really-
6869 // finished... so let the waiters still wait.
6870 mLastWin = null;
6871 mLastBinder = null;
6872 }
6873 mFinished = true;
6874 notifyAll();
6875 }
6876 }
6877
6878 private class KeyQ extends KeyInputQueue
6879 implements KeyInputQueue.FilterCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 KeyQ() {
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006881 super(mContext, WindowManagerService.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 }
6883
6884 @Override
6885 boolean preprocessEvent(InputDevice device, RawInputEvent event) {
6886 if (mPolicy.preprocessInputEventTq(event)) {
6887 return true;
6888 }
Romain Guy06882f82009-06-10 13:36:04 -07006889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 switch (event.type) {
6891 case RawInputEvent.EV_KEY: {
6892 // XXX begin hack
6893 if (DEBUG) {
6894 if (event.keycode == KeyEvent.KEYCODE_G) {
6895 if (event.value != 0) {
6896 // G down
6897 mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
6898 }
6899 return false;
6900 }
6901 if (event.keycode == KeyEvent.KEYCODE_D) {
6902 if (event.value != 0) {
6903 //dump();
6904 }
6905 return false;
6906 }
6907 }
6908 // XXX end hack
Romain Guy06882f82009-06-10 13:36:04 -07006909
Charles Mendis322591c2009-10-29 11:06:59 -07006910 boolean screenIsOff = !mPowerManager.isScreenOn();
6911 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
Romain Guy06882f82009-06-10 13:36:04 -07006913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006914 if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
6915 mPowerManager.goToSleep(event.when);
6916 }
6917
6918 if (screenIsOff) {
6919 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6920 }
6921 if (screenIsDim) {
6922 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6923 }
6924 if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
6925 mPowerManager.userActivity(event.when, false,
Michael Chane96440f2009-05-06 10:27:36 -07006926 LocalPowerManager.BUTTON_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006927 }
Romain Guy06882f82009-06-10 13:36:04 -07006928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
6930 if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
6931 filterQueue(this);
6932 mKeyWaiter.appSwitchComing();
6933 }
6934 return true;
6935 } else {
6936 return false;
6937 }
6938 }
Romain Guy06882f82009-06-10 13:36:04 -07006939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006940 case RawInputEvent.EV_REL: {
Charles Mendis322591c2009-10-29 11:06:59 -07006941 boolean screenIsOff = !mPowerManager.isScreenOn();
6942 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 if (screenIsOff) {
6944 if (!mPolicy.isWakeRelMovementTq(event.deviceId,
6945 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006946 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006947 return false;
6948 }
6949 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6950 }
6951 if (screenIsDim) {
6952 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6953 }
6954 return true;
6955 }
Romain Guy06882f82009-06-10 13:36:04 -07006956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 case RawInputEvent.EV_ABS: {
Charles Mendis322591c2009-10-29 11:06:59 -07006958 boolean screenIsOff = !mPowerManager.isScreenOn();
6959 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006960 if (screenIsOff) {
6961 if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
6962 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006963 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 return false;
6965 }
6966 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6967 }
6968 if (screenIsDim) {
6969 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6970 }
6971 return true;
6972 }
Romain Guy06882f82009-06-10 13:36:04 -07006973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006974 default:
6975 return true;
6976 }
6977 }
6978
6979 public int filterEvent(QueuedEvent ev) {
6980 switch (ev.classType) {
6981 case RawInputEvent.CLASS_KEYBOARD:
6982 KeyEvent ke = (KeyEvent)ev.event;
6983 if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006984 Slog.w(TAG, "Dropping movement key during app switch: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 + ke.getKeyCode() + ", action=" + ke.getAction());
6986 return FILTER_REMOVE;
6987 }
6988 return FILTER_ABORT;
6989 default:
6990 return FILTER_KEEP;
6991 }
6992 }
Michael Chan53071d62009-05-13 17:29:48 -07006993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006994
6995 public boolean detectSafeMode() {
6996 mSafeMode = mPolicy.detectSafeMode();
6997 return mSafeMode;
6998 }
Romain Guy06882f82009-06-10 13:36:04 -07006999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 public void systemReady() {
7001 mPolicy.systemReady();
7002 }
Romain Guy06882f82009-06-10 13:36:04 -07007003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007004 private final class InputDispatcherThread extends Thread {
7005 // Time to wait when there is nothing to do: 9999 seconds.
7006 static final int LONG_WAIT=9999*1000;
7007
7008 public InputDispatcherThread() {
7009 super("InputDispatcher");
7010 }
Romain Guy06882f82009-06-10 13:36:04 -07007011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 @Override
7013 public void run() {
7014 while (true) {
7015 try {
7016 process();
7017 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007018 Slog.e(TAG, "Exception in input dispatcher", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007019 }
7020 }
7021 }
Romain Guy06882f82009-06-10 13:36:04 -07007022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 private void process() {
7024 android.os.Process.setThreadPriority(
7025 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -07007026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 // The last key event we saw
7028 KeyEvent lastKey = null;
7029
7030 // Last keydown time for auto-repeating keys
7031 long lastKeyTime = SystemClock.uptimeMillis();
7032 long nextKeyTime = lastKeyTime+LONG_WAIT;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007033 long downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034
Romain Guy06882f82009-06-10 13:36:04 -07007035 // How many successive repeats we generated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007036 int keyRepeatCount = 0;
7037
7038 // Need to report that configuration has changed?
7039 boolean configChanged = false;
Romain Guy06882f82009-06-10 13:36:04 -07007040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 while (true) {
7042 long curTime = SystemClock.uptimeMillis();
7043
Joe Onorato8a9b2202010-02-26 18:56:32 -08007044 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 TAG, "Waiting for next key: now=" + curTime
7046 + ", repeat @ " + nextKeyTime);
7047
7048 // Retrieve next event, waiting only as long as the next
7049 // repeat timeout. If the configuration has changed, then
7050 // don't wait at all -- we'll report the change as soon as
7051 // we have processed all events.
7052 QueuedEvent ev = mQueue.getEvent(
7053 (int)((!configChanged && curTime < nextKeyTime)
7054 ? (nextKeyTime-curTime) : 0));
7055
Joe Onorato8a9b2202010-02-26 18:56:32 -08007056 if (DEBUG_INPUT && ev != null) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 TAG, "Event: type=" + ev.classType + " data=" + ev.event);
7058
Michael Chan53071d62009-05-13 17:29:48 -07007059 if (MEASURE_LATENCY) {
7060 lt.sample("2 got event ", System.nanoTime() - ev.whenNano);
7061 }
7062
Mike Lockwood3d0ea722009-10-21 22:58:29 -04007063 if (lastKey != null && !mPolicy.allowKeyRepeat()) {
7064 // cancel key repeat at the request of the policy.
7065 lastKey = null;
7066 downTime = 0;
7067 lastKeyTime = curTime;
7068 nextKeyTime = curTime + LONG_WAIT;
7069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007070 try {
7071 if (ev != null) {
Michael Chan53071d62009-05-13 17:29:48 -07007072 curTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007073 int eventType;
7074 if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
7075 eventType = eventType((MotionEvent)ev.event);
7076 } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
7077 ev.classType == RawInputEvent.CLASS_TRACKBALL) {
7078 eventType = LocalPowerManager.BUTTON_EVENT;
7079 } else {
7080 eventType = LocalPowerManager.OTHER_EVENT;
7081 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07007082 try {
Michael Chan53071d62009-05-13 17:29:48 -07007083 if ((curTime - mLastBatteryStatsCallTime)
Michael Chane96440f2009-05-06 10:27:36 -07007084 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
Michael Chan53071d62009-05-13 17:29:48 -07007085 mLastBatteryStatsCallTime = curTime;
Michael Chane96440f2009-05-06 10:27:36 -07007086 mBatteryStats.noteInputEvent();
7087 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07007088 } catch (RemoteException e) {
7089 // Ignore
7090 }
Michael Chane10de972009-05-18 11:24:50 -07007091
Mike Lockwood5db42402009-11-30 14:51:51 -05007092 if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
7093 // do not wake screen in this case
7094 } else if (eventType != TOUCH_EVENT
Michael Chane10de972009-05-18 11:24:50 -07007095 && eventType != LONG_TOUCH_EVENT
7096 && eventType != CHEEK_EVENT) {
7097 mPowerManager.userActivity(curTime, false,
7098 eventType, false);
7099 } else if (mLastTouchEventType != eventType
7100 || (curTime - mLastUserActivityCallTime)
7101 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
7102 mLastUserActivityCallTime = curTime;
7103 mLastTouchEventType = eventType;
7104 mPowerManager.userActivity(curTime, false,
7105 eventType, false);
7106 }
7107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007108 switch (ev.classType) {
7109 case RawInputEvent.CLASS_KEYBOARD:
7110 KeyEvent ke = (KeyEvent)ev.event;
7111 if (ke.isDown()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 lastKeyTime = curTime;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007113 if (lastKey != null &&
7114 ke.getKeyCode() == lastKey.getKeyCode()) {
7115 keyRepeatCount++;
7116 // Arbitrary long timeout to block
7117 // repeating here since we know that
7118 // the device driver takes care of it.
7119 nextKeyTime = lastKeyTime + LONG_WAIT;
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07007120 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007121 TAG, "Received repeated key down");
7122 } else {
7123 downTime = curTime;
7124 keyRepeatCount = 0;
7125 nextKeyTime = lastKeyTime
7126 + ViewConfiguration.getLongPressTimeout();
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07007127 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007128 TAG, "Received key down: first repeat @ "
7129 + nextKeyTime);
7130 }
7131 lastKey = ke;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 } else {
7133 lastKey = null;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007134 downTime = 0;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007135 keyRepeatCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136 // Arbitrary long timeout.
7137 lastKeyTime = curTime;
7138 nextKeyTime = curTime + LONG_WAIT;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007139 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007140 TAG, "Received key up: ignore repeat @ "
7141 + nextKeyTime);
7142 }
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007143 if (keyRepeatCount > 0) {
7144 dispatchKey(KeyEvent.changeTimeRepeat(ke,
7145 ke.getEventTime(), keyRepeatCount), 0, 0);
7146 } else {
7147 dispatchKey(ke, 0, 0);
7148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 mQueue.recycleEvent(ev);
7150 break;
7151 case RawInputEvent.CLASS_TOUCHSCREEN:
Joe Onorato8a9b2202010-02-26 18:56:32 -08007152 //Slog.i(TAG, "Read next event " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007153 dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
7154 break;
7155 case RawInputEvent.CLASS_TRACKBALL:
7156 dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
7157 break;
7158 case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
7159 configChanged = true;
7160 break;
7161 default:
7162 mQueue.recycleEvent(ev);
7163 break;
7164 }
Romain Guy06882f82009-06-10 13:36:04 -07007165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007166 } else if (configChanged) {
7167 configChanged = false;
7168 sendNewConfiguration();
Romain Guy06882f82009-06-10 13:36:04 -07007169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 } else if (lastKey != null) {
7171 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007173 // Timeout occurred while key was down. If it is at or
7174 // past the key repeat time, dispatch the repeat.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007175 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007176 TAG, "Key timeout: repeat=" + nextKeyTime
7177 + ", now=" + curTime);
7178 if (curTime < nextKeyTime) {
7179 continue;
7180 }
Romain Guy06882f82009-06-10 13:36:04 -07007181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 lastKeyTime = nextKeyTime;
7183 nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
7184 keyRepeatCount++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007185 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007186 TAG, "Key repeat: count=" + keyRepeatCount
7187 + ", next @ " + nextKeyTime);
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007188 KeyEvent newEvent;
7189 if (downTime != 0 && (downTime
7190 + ViewConfiguration.getLongPressTimeout())
7191 <= curTime) {
7192 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7193 curTime, keyRepeatCount,
7194 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
7195 downTime = 0;
7196 } else {
7197 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7198 curTime, keyRepeatCount);
7199 }
7200 dispatchKey(newEvent, 0, 0);
Romain Guy06882f82009-06-10 13:36:04 -07007201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 } else {
7203 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 lastKeyTime = curTime;
7206 nextKeyTime = curTime + LONG_WAIT;
7207 }
Romain Guy06882f82009-06-10 13:36:04 -07007208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007209 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007210 Slog.e(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 "Input thread received uncaught exception: " + e, e);
7212 }
7213 }
7214 }
7215 }
7216
7217 // -------------------------------------------------------------
7218 // Client Session State
7219 // -------------------------------------------------------------
7220
7221 private final class Session extends IWindowSession.Stub
7222 implements IBinder.DeathRecipient {
7223 final IInputMethodClient mClient;
7224 final IInputContext mInputContext;
7225 final int mUid;
7226 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007227 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 SurfaceSession mSurfaceSession;
7229 int mNumWindow = 0;
7230 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07007231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007232 /**
7233 * Current pointer move event being dispatched to client window... must
7234 * hold key lock to access.
7235 */
7236 QueuedEvent mPendingPointerMove;
7237 WindowState mPendingPointerWindow;
Romain Guy06882f82009-06-10 13:36:04 -07007238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007239 /**
7240 * Current trackball move event being dispatched to client window... must
7241 * hold key lock to access.
7242 */
7243 QueuedEvent mPendingTrackballMove;
7244 WindowState mPendingTrackballWindow;
7245
7246 public Session(IInputMethodClient client, IInputContext inputContext) {
7247 mClient = client;
7248 mInputContext = inputContext;
7249 mUid = Binder.getCallingUid();
7250 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007251 StringBuilder sb = new StringBuilder();
7252 sb.append("Session{");
7253 sb.append(Integer.toHexString(System.identityHashCode(this)));
7254 sb.append(" uid ");
7255 sb.append(mUid);
7256 sb.append("}");
7257 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07007258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 synchronized (mWindowMap) {
7260 if (mInputMethodManager == null && mHaveInputMethods) {
7261 IBinder b = ServiceManager.getService(
7262 Context.INPUT_METHOD_SERVICE);
7263 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
7264 }
7265 }
7266 long ident = Binder.clearCallingIdentity();
7267 try {
7268 // Note: it is safe to call in to the input method manager
7269 // here because we are not holding our lock.
7270 if (mInputMethodManager != null) {
7271 mInputMethodManager.addClient(client, inputContext,
7272 mUid, mPid);
7273 } else {
7274 client.setUsingInputMethod(false);
7275 }
7276 client.asBinder().linkToDeath(this, 0);
7277 } catch (RemoteException e) {
7278 // The caller has died, so we can just forget about this.
7279 try {
7280 if (mInputMethodManager != null) {
7281 mInputMethodManager.removeClient(client);
7282 }
7283 } catch (RemoteException ee) {
7284 }
7285 } finally {
7286 Binder.restoreCallingIdentity(ident);
7287 }
7288 }
Romain Guy06882f82009-06-10 13:36:04 -07007289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 @Override
7291 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
7292 throws RemoteException {
7293 try {
7294 return super.onTransact(code, data, reply, flags);
7295 } catch (RuntimeException e) {
7296 // Log all 'real' exceptions thrown to the caller
7297 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007298 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 }
7300 throw e;
7301 }
7302 }
7303
7304 public void binderDied() {
7305 // Note: it is safe to call in to the input method manager
7306 // here because we are not holding our lock.
7307 try {
7308 if (mInputMethodManager != null) {
7309 mInputMethodManager.removeClient(mClient);
7310 }
7311 } catch (RemoteException e) {
7312 }
7313 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07007314 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007315 mClientDead = true;
7316 killSessionLocked();
7317 }
7318 }
7319
7320 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac02010-04-22 18:58:52 -07007321 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
7322 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
7323 outInputChannel);
7324 }
7325
7326 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07007328 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 }
Romain Guy06882f82009-06-10 13:36:04 -07007330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007331 public void remove(IWindow window) {
7332 removeWindow(this, window);
7333 }
Romain Guy06882f82009-06-10 13:36:04 -07007334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
7336 int requestedWidth, int requestedHeight, int viewFlags,
7337 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007338 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007339 return relayoutWindow(this, window, attrs,
7340 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007341 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 }
Romain Guy06882f82009-06-10 13:36:04 -07007343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 public void setTransparentRegion(IWindow window, Region region) {
7345 setTransparentRegionWindow(this, window, region);
7346 }
Romain Guy06882f82009-06-10 13:36:04 -07007347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007348 public void setInsets(IWindow window, int touchableInsets,
7349 Rect contentInsets, Rect visibleInsets) {
7350 setInsetsWindow(this, window, touchableInsets, contentInsets,
7351 visibleInsets);
7352 }
Romain Guy06882f82009-06-10 13:36:04 -07007353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007354 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
7355 getWindowDisplayFrame(this, window, outDisplayFrame);
7356 }
Romain Guy06882f82009-06-10 13:36:04 -07007357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007359 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007360 TAG, "IWindow finishDrawing called for " + window);
7361 finishDrawingWindow(this, window);
7362 }
7363
7364 public void finishKey(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007365 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 TAG, "IWindow finishKey called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007367 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7368 throw new IllegalStateException("Should not be called anymore.");
7369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007370 mKeyWaiter.finishedKey(this, window, false,
7371 KeyWaiter.RETURN_NOTHING);
7372 }
7373
7374 public MotionEvent getPendingPointerMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007375 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007376 TAG, "IWindow getPendingMotionEvent called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007377 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7378 throw new IllegalStateException("Should not be called anymore.");
7379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 return mKeyWaiter.finishedKey(this, window, false,
7381 KeyWaiter.RETURN_PENDING_POINTER);
7382 }
Romain Guy06882f82009-06-10 13:36:04 -07007383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 public MotionEvent getPendingTrackballMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007385 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 TAG, "IWindow getPendingMotionEvent called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007387 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7388 throw new IllegalStateException("Should not be called anymore.");
7389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007390 return mKeyWaiter.finishedKey(this, window, false,
7391 KeyWaiter.RETURN_PENDING_TRACKBALL);
7392 }
7393
7394 public void setInTouchMode(boolean mode) {
7395 synchronized(mWindowMap) {
7396 mInTouchMode = mode;
7397 }
7398 }
7399
7400 public boolean getInTouchMode() {
7401 synchronized(mWindowMap) {
7402 return mInTouchMode;
7403 }
7404 }
7405
7406 public boolean performHapticFeedback(IWindow window, int effectId,
7407 boolean always) {
7408 synchronized(mWindowMap) {
7409 long ident = Binder.clearCallingIdentity();
7410 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007411 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007412 windowForClientLocked(this, window, true),
7413 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007414 } finally {
7415 Binder.restoreCallingIdentity(ident);
7416 }
7417 }
7418 }
Romain Guy06882f82009-06-10 13:36:04 -07007419
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007420 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007421 synchronized(mWindowMap) {
7422 long ident = Binder.clearCallingIdentity();
7423 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007424 setWindowWallpaperPositionLocked(
7425 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007426 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007427 } finally {
7428 Binder.restoreCallingIdentity(ident);
7429 }
7430 }
7431 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007432
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007433 public void wallpaperOffsetsComplete(IBinder window) {
7434 WindowManagerService.this.wallpaperOffsetsComplete(window);
7435 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007436
Dianne Hackborn75804932009-10-20 20:15:20 -07007437 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
7438 int z, Bundle extras, boolean sync) {
7439 synchronized(mWindowMap) {
7440 long ident = Binder.clearCallingIdentity();
7441 try {
7442 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007443 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07007444 action, x, y, z, extras, sync);
7445 } finally {
7446 Binder.restoreCallingIdentity(ident);
7447 }
7448 }
7449 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007450
Dianne Hackborn75804932009-10-20 20:15:20 -07007451 public void wallpaperCommandComplete(IBinder window, Bundle result) {
7452 WindowManagerService.this.wallpaperCommandComplete(window, result);
7453 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 void windowAddedLocked() {
7456 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007457 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007458 TAG, "First window added to " + this + ", creating SurfaceSession");
7459 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007460 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007461 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 mSessions.add(this);
7463 }
7464 mNumWindow++;
7465 }
7466
7467 void windowRemovedLocked() {
7468 mNumWindow--;
7469 killSessionLocked();
7470 }
Romain Guy06882f82009-06-10 13:36:04 -07007471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007472 void killSessionLocked() {
7473 if (mNumWindow <= 0 && mClientDead) {
7474 mSessions.remove(this);
7475 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007476 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 TAG, "Last window removed from " + this
7478 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007479 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007480 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 try {
7482 mSurfaceSession.kill();
7483 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007484 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 + mSurfaceSession + " in session " + this
7486 + ": " + e.toString());
7487 }
7488 mSurfaceSession = null;
7489 }
7490 }
7491 }
Romain Guy06882f82009-06-10 13:36:04 -07007492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007493 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007494 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
7495 pw.print(" mClientDead="); pw.print(mClientDead);
7496 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
7497 if (mPendingPointerWindow != null || mPendingPointerMove != null) {
7498 pw.print(prefix);
7499 pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
7500 pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
7501 }
7502 if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
7503 pw.print(prefix);
7504 pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
7505 pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
7506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007507 }
7508
7509 @Override
7510 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007511 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 }
7513 }
7514
7515 // -------------------------------------------------------------
7516 // Client Window State
7517 // -------------------------------------------------------------
7518
7519 private final class WindowState implements WindowManagerPolicy.WindowState {
7520 final Session mSession;
7521 final IWindow mClient;
7522 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07007523 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 AppWindowToken mAppToken;
7525 AppWindowToken mTargetAppToken;
7526 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
7527 final DeathRecipient mDeathRecipient;
7528 final WindowState mAttachedWindow;
7529 final ArrayList mChildWindows = new ArrayList();
7530 final int mBaseLayer;
7531 final int mSubLayer;
7532 final boolean mLayoutAttached;
7533 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007534 final boolean mIsWallpaper;
7535 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 int mViewVisibility;
7537 boolean mPolicyVisibility = true;
7538 boolean mPolicyVisibilityAfterAnim = true;
7539 boolean mAppFreezing;
7540 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007541 boolean mReportDestroySurface;
7542 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 boolean mAttachedHidden; // is our parent window hidden?
7544 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007545 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007546 int mRequestedWidth;
7547 int mRequestedHeight;
7548 int mLastRequestedWidth;
7549 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007550 int mLayer;
7551 int mAnimLayer;
7552 int mLastLayer;
7553 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007554 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007555 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007556
7557 WindowState mNextOutsideTouch;
Romain Guy06882f82009-06-10 13:36:04 -07007558
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007559 int mLayoutSeq = -1;
7560
7561 Configuration mConfiguration = null;
7562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007563 // Actual frame shown on-screen (may be modified by animation)
7564 final Rect mShownFrame = new Rect();
7565 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007568 * Set when we have changed the size of the surface, to know that
7569 * we must tell them application to resize (and thus redraw itself).
7570 */
7571 boolean mSurfaceResized;
7572
7573 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007574 * Insets that determine the actually visible area
7575 */
7576 final Rect mVisibleInsets = new Rect();
7577 final Rect mLastVisibleInsets = new Rect();
7578 boolean mVisibleInsetsChanged;
7579
7580 /**
7581 * Insets that are covered by system windows
7582 */
7583 final Rect mContentInsets = new Rect();
7584 final Rect mLastContentInsets = new Rect();
7585 boolean mContentInsetsChanged;
7586
7587 /**
7588 * Set to true if we are waiting for this window to receive its
7589 * given internal insets before laying out other windows based on it.
7590 */
7591 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07007592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007593 /**
7594 * These are the content insets that were given during layout for
7595 * this window, to be applied to windows behind it.
7596 */
7597 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007599 /**
7600 * These are the visible insets that were given during layout for
7601 * this window, to be applied to windows behind it.
7602 */
7603 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007605 /**
7606 * Flag indicating whether the touchable region should be adjusted by
7607 * the visible insets; if false the area outside the visible insets is
7608 * NOT touchable, so we must use those to adjust the frame during hit
7609 * tests.
7610 */
7611 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07007612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007613 // Current transformation being applied.
7614 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
7615 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
7616 float mHScale=1, mVScale=1;
7617 float mLastHScale=1, mLastVScale=1;
7618 final Matrix mTmpMatrix = new Matrix();
7619
7620 // "Real" frame that the application sees.
7621 final Rect mFrame = new Rect();
7622 final Rect mLastFrame = new Rect();
7623
7624 final Rect mContainingFrame = new Rect();
7625 final Rect mDisplayFrame = new Rect();
7626 final Rect mContentFrame = new Rect();
7627 final Rect mVisibleFrame = new Rect();
7628
7629 float mShownAlpha = 1;
7630 float mAlpha = 1;
7631 float mLastAlpha = 1;
7632
7633 // Set to true if, when the window gets displayed, it should perform
7634 // an enter animation.
7635 boolean mEnterAnimationPending;
7636
7637 // Currently running animation.
7638 boolean mAnimating;
7639 boolean mLocalAnimating;
7640 Animation mAnimation;
7641 boolean mAnimationIsEntrance;
7642 boolean mHasTransformation;
7643 boolean mHasLocalTransformation;
7644 final Transformation mTransformation = new Transformation();
7645
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007646 // If a window showing a wallpaper: the requested offset for the
7647 // wallpaper; if a wallpaper window: the currently applied offset.
7648 float mWallpaperX = -1;
7649 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007650
7651 // If a window showing a wallpaper: what fraction of the offset
7652 // range corresponds to a full virtual screen.
7653 float mWallpaperXStep = -1;
7654 float mWallpaperYStep = -1;
7655
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007656 // Wallpaper windows: pixels offset based on above variables.
7657 int mXOffset;
7658 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007660 // This is set after IWindowSession.relayout() has been called at
7661 // least once for the window. It allows us to detect the situation
7662 // where we don't yet have a surface, but should have one soon, so
7663 // we can give the window focus before waiting for the relayout.
7664 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 // This is set after the Surface has been created but before the
7667 // window has been drawn. During this time the surface is hidden.
7668 boolean mDrawPending;
7669
7670 // This is set after the window has finished drawing for the first
7671 // time but before its surface is shown. The surface will be
7672 // displayed when the next layout is run.
7673 boolean mCommitDrawPending;
7674
7675 // This is set during the time after the window's drawing has been
7676 // committed, and before its surface is actually shown. It is used
7677 // to delay showing the surface until all windows in a token are ready
7678 // to be shown.
7679 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007681 // Set when the window has been shown in the screen the first time.
7682 boolean mHasDrawn;
7683
7684 // Currently running an exit animation?
7685 boolean mExiting;
7686
7687 // Currently on the mDestroySurface list?
7688 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007690 // Completely remove from window manager after exit animation?
7691 boolean mRemoveOnExit;
7692
7693 // Set when the orientation is changing and this window has not yet
7694 // been updated for the new orientation.
7695 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007697 // Is this window now (or just being) removed?
7698 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007699
Dianne Hackborn16064f92010-03-25 00:47:24 -07007700 // For debugging, this is the last information given to the surface flinger.
7701 boolean mSurfaceShown;
7702 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7703 int mSurfaceLayer;
7704 float mSurfaceAlpha;
7705
Jeff Brown46b9ac02010-04-22 18:58:52 -07007706 // Input channel
7707 InputChannel mInputChannel;
7708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007709 WindowState(Session s, IWindow c, WindowToken token,
7710 WindowState attachedWindow, WindowManager.LayoutParams a,
7711 int viewVisibility) {
7712 mSession = s;
7713 mClient = c;
7714 mToken = token;
7715 mAttrs.copyFrom(a);
7716 mViewVisibility = viewVisibility;
7717 DeathRecipient deathRecipient = new DeathRecipient();
7718 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007719 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 TAG, "Window " + this + " client=" + c.asBinder()
7721 + " token=" + token + " (" + mAttrs.token + ")");
7722 try {
7723 c.asBinder().linkToDeath(deathRecipient, 0);
7724 } catch (RemoteException e) {
7725 mDeathRecipient = null;
7726 mAttachedWindow = null;
7727 mLayoutAttached = false;
7728 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007729 mIsWallpaper = false;
7730 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 mBaseLayer = 0;
7732 mSubLayer = 0;
7733 return;
7734 }
7735 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007737 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7738 mAttrs.type <= LAST_SUB_WINDOW)) {
7739 // The multiplier here is to reserve space for multiple
7740 // windows in the same type layer.
7741 mBaseLayer = mPolicy.windowTypeToLayerLw(
7742 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7743 + TYPE_LAYER_OFFSET;
7744 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7745 mAttachedWindow = attachedWindow;
7746 mAttachedWindow.mChildWindows.add(this);
7747 mLayoutAttached = mAttrs.type !=
7748 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7749 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7750 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007751 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7752 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 } else {
7754 // The multiplier here is to reserve space for multiple
7755 // windows in the same type layer.
7756 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7757 * TYPE_LAYER_MULTIPLIER
7758 + TYPE_LAYER_OFFSET;
7759 mSubLayer = 0;
7760 mAttachedWindow = null;
7761 mLayoutAttached = false;
7762 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7763 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007764 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7765 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007766 }
7767
7768 WindowState appWin = this;
7769 while (appWin.mAttachedWindow != null) {
7770 appWin = mAttachedWindow;
7771 }
7772 WindowToken appToken = appWin.mToken;
7773 while (appToken.appWindowToken == null) {
7774 WindowToken parent = mTokenMap.get(appToken.token);
7775 if (parent == null || appToken == parent) {
7776 break;
7777 }
7778 appToken = parent;
7779 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007780 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007781 mAppToken = appToken.appWindowToken;
7782
7783 mSurface = null;
7784 mRequestedWidth = 0;
7785 mRequestedHeight = 0;
7786 mLastRequestedWidth = 0;
7787 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007788 mXOffset = 0;
7789 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790 mLayer = 0;
7791 mAnimLayer = 0;
7792 mLastLayer = 0;
7793 }
7794
7795 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007796 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007797 TAG, "Attaching " + this + " token=" + mToken
7798 + ", list=" + mToken.windows);
7799 mSession.windowAddedLocked();
7800 }
7801
7802 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7803 mHaveFrame = true;
7804
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007805 final Rect container = mContainingFrame;
7806 container.set(pf);
7807
7808 final Rect display = mDisplayFrame;
7809 display.set(df);
7810
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007811 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007812 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007813 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7814 display.intersect(mCompatibleScreenFrame);
7815 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007816 }
7817
7818 final int pw = container.right - container.left;
7819 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007820
7821 int w,h;
7822 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7823 w = mAttrs.width < 0 ? pw : mAttrs.width;
7824 h = mAttrs.height< 0 ? ph : mAttrs.height;
7825 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007826 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7827 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007828 }
Romain Guy06882f82009-06-10 13:36:04 -07007829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007830 final Rect content = mContentFrame;
7831 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007833 final Rect visible = mVisibleFrame;
7834 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007836 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007837 final int fw = frame.width();
7838 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7841 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7842
7843 Gravity.apply(mAttrs.gravity, w, h, container,
7844 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7845 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7846
7847 //System.out.println("Out: " + mFrame);
7848
7849 // Now make sure the window fits in the overall display.
7850 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852 // Make sure the content and visible frames are inside of the
7853 // final window frame.
7854 if (content.left < frame.left) content.left = frame.left;
7855 if (content.top < frame.top) content.top = frame.top;
7856 if (content.right > frame.right) content.right = frame.right;
7857 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7858 if (visible.left < frame.left) visible.left = frame.left;
7859 if (visible.top < frame.top) visible.top = frame.top;
7860 if (visible.right > frame.right) visible.right = frame.right;
7861 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007863 final Rect contentInsets = mContentInsets;
7864 contentInsets.left = content.left-frame.left;
7865 contentInsets.top = content.top-frame.top;
7866 contentInsets.right = frame.right-content.right;
7867 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 final Rect visibleInsets = mVisibleInsets;
7870 visibleInsets.left = visible.left-frame.left;
7871 visibleInsets.top = visible.top-frame.top;
7872 visibleInsets.right = frame.right-visible.right;
7873 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007874
Dianne Hackborn284ac932009-08-28 10:34:25 -07007875 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7876 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007877 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007878 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007880 if (localLOGV) {
7881 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7882 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007883 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007884 + mRequestedWidth + ", mRequestedheight="
7885 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7886 + "): frame=" + mFrame.toShortString()
7887 + " ci=" + contentInsets.toShortString()
7888 + " vi=" + visibleInsets.toShortString());
7889 //}
7890 }
7891 }
Romain Guy06882f82009-06-10 13:36:04 -07007892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007893 public Rect getFrameLw() {
7894 return mFrame;
7895 }
7896
7897 public Rect getShownFrameLw() {
7898 return mShownFrame;
7899 }
7900
7901 public Rect getDisplayFrameLw() {
7902 return mDisplayFrame;
7903 }
7904
7905 public Rect getContentFrameLw() {
7906 return mContentFrame;
7907 }
7908
7909 public Rect getVisibleFrameLw() {
7910 return mVisibleFrame;
7911 }
7912
7913 public boolean getGivenInsetsPendingLw() {
7914 return mGivenInsetsPending;
7915 }
7916
7917 public Rect getGivenContentInsetsLw() {
7918 return mGivenContentInsets;
7919 }
Romain Guy06882f82009-06-10 13:36:04 -07007920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 public Rect getGivenVisibleInsetsLw() {
7922 return mGivenVisibleInsets;
7923 }
Romain Guy06882f82009-06-10 13:36:04 -07007924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 public WindowManager.LayoutParams getAttrs() {
7926 return mAttrs;
7927 }
7928
7929 public int getSurfaceLayer() {
7930 return mLayer;
7931 }
Romain Guy06882f82009-06-10 13:36:04 -07007932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 public IApplicationToken getAppToken() {
7934 return mAppToken != null ? mAppToken.appToken : null;
7935 }
Jeff Brown349703e2010-06-22 01:27:15 -07007936
7937 public long getInputDispatchingTimeoutNanos() {
7938 return mAppToken != null
7939 ? mAppToken.inputDispatchingTimeoutNanos
7940 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007942
7943 public boolean hasAppShownWindows() {
7944 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7945 }
7946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007947 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007948 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007949 TAG, "Setting animation in " + this + ": " + anim);
7950 mAnimating = false;
7951 mLocalAnimating = false;
7952 mAnimation = anim;
7953 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7954 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7955 }
7956
7957 public void clearAnimation() {
7958 if (mAnimation != null) {
7959 mAnimating = true;
7960 mLocalAnimating = false;
7961 mAnimation = null;
7962 }
7963 }
Romain Guy06882f82009-06-10 13:36:04 -07007964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007965 Surface createSurfaceLocked() {
7966 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007967 mReportDestroySurface = false;
7968 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 mDrawPending = true;
7970 mCommitDrawPending = false;
7971 mReadyToShow = false;
7972 if (mAppToken != null) {
7973 mAppToken.allDrawn = false;
7974 }
7975
7976 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07007977 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007978 flags |= Surface.PUSH_BUFFERS;
7979 }
7980
7981 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7982 flags |= Surface.SECURE;
7983 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007984 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 TAG, "Creating surface in session "
7986 + mSession.mSurfaceSession + " window " + this
7987 + " w=" + mFrame.width()
7988 + " h=" + mFrame.height() + " format="
7989 + mAttrs.format + " flags=" + flags);
7990
7991 int w = mFrame.width();
7992 int h = mFrame.height();
7993 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7994 // for a scaled surface, we always want the requested
7995 // size.
7996 w = mRequestedWidth;
7997 h = mRequestedHeight;
7998 }
7999
Romain Guy9825ec62009-10-01 00:58:09 -07008000 // Something is wrong and SurfaceFlinger will not like this,
8001 // try to revert to sane values
8002 if (w <= 0) w = 1;
8003 if (h <= 0) h = 1;
8004
Dianne Hackborn16064f92010-03-25 00:47:24 -07008005 mSurfaceShown = false;
8006 mSurfaceLayer = 0;
8007 mSurfaceAlpha = 1;
8008 mSurfaceX = 0;
8009 mSurfaceY = 0;
8010 mSurfaceW = w;
8011 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 try {
8013 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07008014 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08008015 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008016 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008017 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008018 + mSurface + " IN SESSION "
8019 + mSession.mSurfaceSession
8020 + ": pid=" + mSession.mPid + " format="
8021 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008022 + Integer.toHexString(flags)
8023 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008025 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 reclaimSomeSurfaceMemoryLocked(this, "create");
8027 return null;
8028 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008029 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008030 return null;
8031 }
Romain Guy06882f82009-06-10 13:36:04 -07008032
Joe Onorato8a9b2202010-02-26 18:56:32 -08008033 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 TAG, "Got surface: " + mSurface
8035 + ", set left=" + mFrame.left + " top=" + mFrame.top
8036 + ", animLayer=" + mAnimLayer);
8037 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008038 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008039 if (SHOW_TRANSACTIONS) logSurface(this,
8040 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
8041 mFrame.width() + "x" + mFrame.height() + "), layer=" +
8042 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 }
8044 Surface.openTransaction();
8045 try {
8046 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008047 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07008048 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07008049 mSurface.setPosition(mSurfaceX, mSurfaceY);
8050 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008052 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008053 mSurface.hide();
8054 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008055 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 mSurface.setFlags(Surface.SURFACE_DITHER,
8057 Surface.SURFACE_DITHER);
8058 }
8059 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008060 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 reclaimSomeSurfaceMemoryLocked(this, "create-init");
8062 }
8063 mLastHidden = true;
8064 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008065 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066 Surface.closeTransaction();
8067 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008068 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008069 TAG, "Created surface " + this);
8070 }
8071 return mSurface;
8072 }
Romain Guy06882f82009-06-10 13:36:04 -07008073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008074 void destroySurfaceLocked() {
8075 // Window is no longer on-screen, so can no longer receive
8076 // key events... if we were waiting for it to finish
8077 // handling a key event, the wait is over!
Jeff Brown349703e2010-06-22 01:27:15 -07008078 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
8079 mKeyWaiter.finishedKey(mSession, mClient, true,
8080 KeyWaiter.RETURN_NOTHING);
8081 mKeyWaiter.releasePendingPointerLocked(mSession);
8082 mKeyWaiter.releasePendingTrackballLocked(mSession);
8083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008084
8085 if (mAppToken != null && this == mAppToken.startingWindow) {
8086 mAppToken.startingDisplayed = false;
8087 }
Romain Guy06882f82009-06-10 13:36:04 -07008088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008090 mDrawPending = false;
8091 mCommitDrawPending = false;
8092 mReadyToShow = false;
8093
8094 int i = mChildWindows.size();
8095 while (i > 0) {
8096 i--;
8097 WindowState c = (WindowState)mChildWindows.get(i);
8098 c.mAttachedHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008099
8100 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8101 mInputMonitor.windowIsBecomingInvisibleLw(c);
8102 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008103 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008104
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008105 if (mReportDestroySurface) {
8106 mReportDestroySurface = false;
8107 mSurfacePendingDestroy = true;
8108 try {
8109 mClient.dispatchGetNewSurface();
8110 // We'll really destroy on the next time around.
8111 return;
8112 } catch (RemoteException e) {
8113 }
8114 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008116 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008117 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008118 RuntimeException e = null;
8119 if (!HIDE_STACK_CRAWLS) {
8120 e = new RuntimeException();
8121 e.fillInStackTrace();
8122 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008123 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008124 + mSurface + ", session " + mSession, e);
8125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008126 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008127 RuntimeException e = null;
8128 if (!HIDE_STACK_CRAWLS) {
8129 e = new RuntimeException();
8130 e.fillInStackTrace();
8131 }
8132 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008134 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008135 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008136 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 + " surface " + mSurface + " session " + mSession
8138 + ": " + e.toString());
8139 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008140
Dianne Hackborn16064f92010-03-25 00:47:24 -07008141 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143 }
8144 }
8145
8146 boolean finishDrawingLocked() {
8147 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008148 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008149 TAG, "finishDrawingLocked: " + mSurface);
8150 mCommitDrawPending = true;
8151 mDrawPending = false;
8152 return true;
8153 }
8154 return false;
8155 }
8156
8157 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008158 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008159 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008161 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008162 }
8163 mCommitDrawPending = false;
8164 mReadyToShow = true;
8165 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
8166 final AppWindowToken atoken = mAppToken;
8167 if (atoken == null || atoken.allDrawn || starting) {
8168 performShowLocked();
8169 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008170 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 }
8172
8173 // This must be called while inside a transaction.
8174 boolean performShowLocked() {
8175 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008176 RuntimeException e = null;
8177 if (!HIDE_STACK_CRAWLS) {
8178 e = new RuntimeException();
8179 e.fillInStackTrace();
8180 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008181 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
8183 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
8184 }
8185 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008186 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
8187 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008188 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 + " during animation: policyVis=" + mPolicyVisibility
8190 + " attHidden=" + mAttachedHidden
8191 + " tok.hiddenRequested="
8192 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07008193 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 + (mAppToken != null ? mAppToken.hidden : false)
8195 + " animating=" + mAnimating
8196 + " tok animating="
8197 + (mAppToken != null ? mAppToken.animating : false));
8198 if (!showSurfaceRobustlyLocked(this)) {
8199 return false;
8200 }
8201 mLastAlpha = -1;
8202 mHasDrawn = true;
8203 mLastHidden = false;
8204 mReadyToShow = false;
8205 enableScreenIfNeededLocked();
8206
8207 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07008208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008209 int i = mChildWindows.size();
8210 while (i > 0) {
8211 i--;
8212 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008213 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008214 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008215 if (c.mSurface != null) {
8216 c.performShowLocked();
8217 // It hadn't been shown, which means layout not
8218 // performed on it, so now we want to make sure to
8219 // do a layout. If called from within the transaction
8220 // loop, this will cause it to restart with a new
8221 // layout.
8222 mLayoutNeeded = true;
8223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008224 }
8225 }
Romain Guy06882f82009-06-10 13:36:04 -07008226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 if (mAttrs.type != TYPE_APPLICATION_STARTING
8228 && mAppToken != null) {
8229 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008230
Dianne Hackborn248b1882009-09-16 16:46:44 -07008231 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008232 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008233 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008234 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07008235 // If this initial window is animating, stop it -- we
8236 // will do an animation to reveal it from behind the
8237 // starting window, so there is no need for it to also
8238 // be doing its own stuff.
8239 if (mAnimation != null) {
8240 mAnimation = null;
8241 // Make sure we clean up the animation.
8242 mAnimating = true;
8243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244 mFinishedStarting.add(mAppToken);
8245 mH.sendEmptyMessage(H.FINISHED_STARTING);
8246 }
8247 mAppToken.updateReportedVisibilityLocked();
8248 }
8249 }
8250 return true;
8251 }
Romain Guy06882f82009-06-10 13:36:04 -07008252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008253 // This must be called while inside a transaction. Returns true if
8254 // there is more animation to run.
8255 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008256 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008257 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008259 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
8260 mHasTransformation = true;
8261 mHasLocalTransformation = true;
8262 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008263 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008264 TAG, "Starting animation in " + this +
8265 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
8266 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
8267 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
8268 mAnimation.setStartTime(currentTime);
8269 mLocalAnimating = true;
8270 mAnimating = true;
8271 }
8272 mTransformation.clear();
8273 final boolean more = mAnimation.getTransformation(
8274 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008275 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276 TAG, "Stepped animation in " + this +
8277 ": more=" + more + ", xform=" + mTransformation);
8278 if (more) {
8279 // we're not done!
8280 return true;
8281 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008282 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 TAG, "Finished animation in " + this +
8284 " @ " + currentTime);
8285 mAnimation = null;
8286 //WindowManagerService.this.dump();
8287 }
8288 mHasLocalTransformation = false;
8289 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008290 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008291 // When our app token is animating, we kind-of pretend like
8292 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
8293 // part of this check means that we will only do this if
8294 // our window is not currently exiting, or it is not
8295 // locally animating itself. The idea being that one that
8296 // is exiting and doing a local animation should be removed
8297 // once that animation is done.
8298 mAnimating = true;
8299 mHasTransformation = true;
8300 mTransformation.clear();
8301 return false;
8302 } else if (mHasTransformation) {
8303 // Little trick to get through the path below to act like
8304 // we have finished an animation.
8305 mAnimating = true;
8306 } else if (isAnimating()) {
8307 mAnimating = true;
8308 }
8309 } else if (mAnimation != null) {
8310 // If the display is frozen, and there is a pending animation,
8311 // clear it and make sure we run the cleanup code.
8312 mAnimating = true;
8313 mLocalAnimating = true;
8314 mAnimation = null;
8315 }
Romain Guy06882f82009-06-10 13:36:04 -07008316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008317 if (!mAnimating && !mLocalAnimating) {
8318 return false;
8319 }
8320
Joe Onorato8a9b2202010-02-26 18:56:32 -08008321 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322 TAG, "Animation done in " + this + ": exiting=" + mExiting
8323 + ", reportedVisible="
8324 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07008325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 mAnimating = false;
8327 mLocalAnimating = false;
8328 mAnimation = null;
8329 mAnimLayer = mLayer;
8330 if (mIsImWindow) {
8331 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008332 } else if (mIsWallpaper) {
8333 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008335 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008336 + " anim layer: " + mAnimLayer);
8337 mHasTransformation = false;
8338 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008339 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
8340 if (DEBUG_VISIBILITY) {
8341 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
8342 + mPolicyVisibilityAfterAnim);
8343 }
8344 mPolicyVisibility = mPolicyVisibilityAfterAnim;
8345 if (!mPolicyVisibility) {
8346 if (mCurrentFocus == this) {
8347 mFocusMayChange = true;
8348 }
8349 // Window is no longer visible -- make sure if we were waiting
8350 // for it to be displayed before enabling the display, that
8351 // we allow the display to be enabled now.
8352 enableScreenIfNeededLocked();
8353 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 mTransformation.clear();
8356 if (mHasDrawn
8357 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
8358 && mAppToken != null
8359 && mAppToken.firstWindowDrawn
8360 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008361 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 + mToken + ": first real window done animating");
8363 mFinishedStarting.add(mAppToken);
8364 mH.sendEmptyMessage(H.FINISHED_STARTING);
8365 }
Romain Guy06882f82009-06-10 13:36:04 -07008366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008367 finishExit();
8368
8369 if (mAppToken != null) {
8370 mAppToken.updateReportedVisibilityLocked();
8371 }
8372
8373 return false;
8374 }
8375
8376 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008377 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008378 TAG, "finishExit in " + this
8379 + ": exiting=" + mExiting
8380 + " remove=" + mRemoveOnExit
8381 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07008382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383 final int N = mChildWindows.size();
8384 for (int i=0; i<N; i++) {
8385 ((WindowState)mChildWindows.get(i)).finishExit();
8386 }
Romain Guy06882f82009-06-10 13:36:04 -07008387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 if (!mExiting) {
8389 return;
8390 }
Romain Guy06882f82009-06-10 13:36:04 -07008391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008392 if (isWindowAnimating()) {
8393 return;
8394 }
8395
Joe Onorato8a9b2202010-02-26 18:56:32 -08008396 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 TAG, "Exit animation finished in " + this
8398 + ": remove=" + mRemoveOnExit);
8399 if (mSurface != null) {
8400 mDestroySurface.add(this);
8401 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008402 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008403 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008404 try {
8405 mSurface.hide();
8406 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008407 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408 }
8409 mLastHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008410
8411 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8412 for (int i=0; i<N; i++) {
8413 mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i));
8414 }
8415 } else {
8416 mKeyWaiter.releasePendingPointerLocked(mSession);
8417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 }
8419 mExiting = false;
8420 if (mRemoveOnExit) {
8421 mPendingRemove.add(this);
8422 mRemoveOnExit = false;
8423 }
8424 }
Romain Guy06882f82009-06-10 13:36:04 -07008425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008426 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
8427 if (dsdx < .99999f || dsdx > 1.00001f) return false;
8428 if (dtdy < .99999f || dtdy > 1.00001f) return false;
8429 if (dtdx < -.000001f || dtdx > .000001f) return false;
8430 if (dsdy < -.000001f || dsdy > .000001f) return false;
8431 return true;
8432 }
Romain Guy06882f82009-06-10 13:36:04 -07008433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008434 void computeShownFrameLocked() {
8435 final boolean selfTransformation = mHasLocalTransformation;
8436 Transformation attachedTransformation =
8437 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
8438 ? mAttachedWindow.mTransformation : null;
8439 Transformation appTransformation =
8440 (mAppToken != null && mAppToken.hasTransformation)
8441 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008442
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008443 // Wallpapers are animated based on the "real" window they
8444 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008445 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008446 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07008447 if (mWallpaperTarget.mHasLocalTransformation &&
8448 mWallpaperTarget.mAnimation != null &&
8449 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008450 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008451 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008452 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008453 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008454 }
8455 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07008456 mWallpaperTarget.mAppToken.hasTransformation &&
8457 mWallpaperTarget.mAppToken.animation != null &&
8458 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008459 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008460 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008461 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008462 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008463 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008464 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 if (selfTransformation || attachedTransformation != null
8467 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07008468 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469 final Rect frame = mFrame;
8470 final float tmpFloats[] = mTmpFloats;
8471 final Matrix tmpMatrix = mTmpMatrix;
8472
8473 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07008474 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008475 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008476 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008477 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07008478 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008480 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008481 }
8482 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008483 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008484 }
8485
8486 // "convert" it into SurfaceFlinger's format
8487 // (a 2x2 matrix + an offset)
8488 // Here we must not transform the position of the surface
8489 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008490 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07008491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008492 tmpMatrix.getValues(tmpFloats);
8493 mDsDx = tmpFloats[Matrix.MSCALE_X];
8494 mDtDx = tmpFloats[Matrix.MSKEW_X];
8495 mDsDy = tmpFloats[Matrix.MSKEW_Y];
8496 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008497 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
8498 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008499 int w = frame.width();
8500 int h = frame.height();
8501 mShownFrame.set(x, y, x+w, y+h);
8502
8503 // Now set the alpha... but because our current hardware
8504 // can't do alpha transformation on a non-opaque surface,
8505 // turn it off if we are running an animation that is also
8506 // transforming since it is more important to have that
8507 // animation be smooth.
8508 mShownAlpha = mAlpha;
8509 if (!mLimitedAlphaCompositing
8510 || (!PixelFormat.formatHasAlpha(mAttrs.format)
8511 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
8512 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008513 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008514 if (selfTransformation) {
8515 mShownAlpha *= mTransformation.getAlpha();
8516 }
8517 if (attachedTransformation != null) {
8518 mShownAlpha *= attachedTransformation.getAlpha();
8519 }
8520 if (appTransformation != null) {
8521 mShownAlpha *= appTransformation.getAlpha();
8522 }
8523 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008524 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 }
Romain Guy06882f82009-06-10 13:36:04 -07008526
Joe Onorato8a9b2202010-02-26 18:56:32 -08008527 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008528 TAG, "Continuing animation in " + this +
8529 ": " + mShownFrame +
8530 ", alpha=" + mTransformation.getAlpha());
8531 return;
8532 }
Romain Guy06882f82009-06-10 13:36:04 -07008533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008535 if (mXOffset != 0 || mYOffset != 0) {
8536 mShownFrame.offset(mXOffset, mYOffset);
8537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008538 mShownAlpha = mAlpha;
8539 mDsDx = 1;
8540 mDtDx = 0;
8541 mDsDy = 0;
8542 mDtDy = 1;
8543 }
Romain Guy06882f82009-06-10 13:36:04 -07008544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545 /**
8546 * Is this window visible? It is not visible if there is no
8547 * surface, or we are in the process of running an exit animation
8548 * that will remove the surface, or its app token has been hidden.
8549 */
8550 public boolean isVisibleLw() {
8551 final AppWindowToken atoken = mAppToken;
8552 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8553 && (atoken == null || !atoken.hiddenRequested)
8554 && !mExiting && !mDestroying;
8555 }
8556
8557 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008558 * Like {@link #isVisibleLw}, but also counts a window that is currently
8559 * "hidden" behind the keyguard as visible. This allows us to apply
8560 * things like window flags that impact the keyguard.
8561 * XXX I am starting to think we need to have ANOTHER visibility flag
8562 * for this "hidden behind keyguard" state rather than overloading
8563 * mPolicyVisibility. Ungh.
8564 */
8565 public boolean isVisibleOrBehindKeyguardLw() {
8566 final AppWindowToken atoken = mAppToken;
8567 return mSurface != null && !mAttachedHidden
8568 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackborn5943c202010-04-12 21:36:49 -07008569 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending))
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008570 && !mExiting && !mDestroying;
8571 }
8572
8573 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008574 * Is this window visible, ignoring its app token? It is not visible
8575 * if there is no surface, or we are in the process of running an exit animation
8576 * that will remove the surface.
8577 */
8578 public boolean isWinVisibleLw() {
8579 final AppWindowToken atoken = mAppToken;
8580 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8581 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
8582 && !mExiting && !mDestroying;
8583 }
8584
8585 /**
8586 * The same as isVisible(), but follows the current hidden state of
8587 * the associated app token, not the pending requested hidden state.
8588 */
8589 boolean isVisibleNow() {
8590 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07008591 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
8593
8594 /**
8595 * Same as isVisible(), but we also count it as visible between the
8596 * call to IWindowSession.add() and the first relayout().
8597 */
8598 boolean isVisibleOrAdding() {
8599 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008600 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
8602 && mPolicyVisibility && !mAttachedHidden
8603 && (atoken == null || !atoken.hiddenRequested)
8604 && !mExiting && !mDestroying;
8605 }
8606
8607 /**
8608 * Is this window currently on-screen? It is on-screen either if it
8609 * is visible or it is currently running an animation before no longer
8610 * being visible.
8611 */
8612 boolean isOnScreen() {
8613 final AppWindowToken atoken = mAppToken;
8614 if (atoken != null) {
8615 return mSurface != null && mPolicyVisibility && !mDestroying
8616 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008617 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 } else {
8619 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008620 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 }
8622 }
Romain Guy06882f82009-06-10 13:36:04 -07008623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008624 /**
8625 * Like isOnScreen(), but we don't return true if the window is part
8626 * of a transition that has not yet been started.
8627 */
8628 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008629 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008630 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008631 return false;
8632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008634 final boolean animating = atoken != null
8635 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008636 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008637 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8638 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008639 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008640 }
8641
8642 /** Is the window or its container currently animating? */
8643 boolean isAnimating() {
8644 final WindowState attached = mAttachedWindow;
8645 final AppWindowToken atoken = mAppToken;
8646 return mAnimation != null
8647 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008648 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008649 (atoken.animation != null
8650 || atoken.inPendingTransaction));
8651 }
8652
8653 /** Is this window currently animating? */
8654 boolean isWindowAnimating() {
8655 return mAnimation != null;
8656 }
8657
8658 /**
8659 * Like isOnScreen, but returns false if the surface hasn't yet
8660 * been drawn.
8661 */
8662 public boolean isDisplayedLw() {
8663 final AppWindowToken atoken = mAppToken;
8664 return mSurface != null && mPolicyVisibility && !mDestroying
8665 && !mDrawPending && !mCommitDrawPending
8666 && ((!mAttachedHidden &&
8667 (atoken == null || !atoken.hiddenRequested))
8668 || mAnimating);
8669 }
8670
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008671 /**
8672 * Returns true if the window has a surface that it has drawn a
Dianne Hackborn5943c202010-04-12 21:36:49 -07008673 * complete UI in to. Note that this returns true if the orientation
8674 * is changing even if the window hasn't redrawn because we don't want
8675 * to stop things from executing during that time.
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008676 */
8677 public boolean isDrawnLw() {
8678 final AppWindowToken atoken = mAppToken;
8679 return mSurface != null && !mDestroying
Dianne Hackborn5943c202010-04-12 21:36:49 -07008680 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending));
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008681 }
8682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683 public boolean fillsScreenLw(int screenWidth, int screenHeight,
8684 boolean shownFrame, boolean onlyOpaque) {
8685 if (mSurface == null) {
8686 return false;
8687 }
8688 if (mAppToken != null && !mAppToken.appFullscreen) {
8689 return false;
8690 }
8691 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
8692 return false;
8693 }
8694 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008695
8696 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
8697 return frame.left <= mCompatibleScreenFrame.left &&
8698 frame.top <= mCompatibleScreenFrame.top &&
8699 frame.right >= mCompatibleScreenFrame.right &&
8700 frame.bottom >= mCompatibleScreenFrame.bottom;
8701 } else {
8702 return frame.left <= 0 && frame.top <= 0
8703 && frame.right >= screenWidth
8704 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 }
Romain Guy06882f82009-06-10 13:36:04 -07008707
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008708 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008709 * Return true if the window is opaque and fully drawn. This indicates
8710 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008711 */
8712 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008713 return (mAttrs.format == PixelFormat.OPAQUE
8714 || mAttrs.type == TYPE_WALLPAPER)
8715 && mSurface != null && mAnimation == null
8716 && (mAppToken == null || mAppToken.animation == null)
8717 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008718 }
8719
8720 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8721 return
8722 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008723 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8724 // only if it's visible
8725 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008726 // and only if the application fills the compatible screen
8727 mFrame.left <= mCompatibleScreenFrame.left &&
8728 mFrame.top <= mCompatibleScreenFrame.top &&
8729 mFrame.right >= mCompatibleScreenFrame.right &&
8730 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008731 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008732 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008733 }
8734
8735 boolean isFullscreen(int screenWidth, int screenHeight) {
8736 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008737 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008738 }
8739
8740 void removeLocked() {
8741 if (mAttachedWindow != null) {
8742 mAttachedWindow.mChildWindows.remove(this);
8743 }
8744 destroySurfaceLocked();
8745 mSession.windowRemovedLocked();
8746 try {
8747 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8748 } catch (RuntimeException e) {
8749 // Ignore if it has already been removed (usually because
8750 // we are doing this as part of processing a death note.)
8751 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07008752
8753 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8754 if (mInputChannel != null) {
8755 mInputManager.unregisterInputChannel(mInputChannel);
8756
8757 mInputChannel.dispose();
8758 mInputChannel = null;
8759 }
8760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 }
8762
8763 private class DeathRecipient implements IBinder.DeathRecipient {
8764 public void binderDied() {
8765 try {
8766 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008767 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008768 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008769 if (win != null) {
8770 removeWindowLocked(mSession, win);
8771 }
8772 }
8773 } catch (IllegalArgumentException ex) {
8774 // This will happen if the window has already been
8775 // removed.
8776 }
8777 }
8778 }
8779
8780 /** Returns true if this window desires key events. */
8781 public final boolean canReceiveKeys() {
8782 return isVisibleOrAdding()
8783 && (mViewVisibility == View.VISIBLE)
8784 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8785 }
8786
8787 public boolean hasDrawnLw() {
8788 return mHasDrawn;
8789 }
8790
8791 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008792 return showLw(doAnimation, true);
8793 }
8794
8795 boolean showLw(boolean doAnimation, boolean requestAnim) {
8796 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8797 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008798 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008799 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008800 if (doAnimation) {
8801 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8802 + mPolicyVisibility + " mAnimation=" + mAnimation);
8803 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8804 doAnimation = false;
8805 } else if (mPolicyVisibility && mAnimation == null) {
8806 // Check for the case where we are currently visible and
8807 // not animating; we do not want to do animation at such a
8808 // point to become visible when we already are.
8809 doAnimation = false;
8810 }
8811 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008812 mPolicyVisibility = true;
8813 mPolicyVisibilityAfterAnim = true;
8814 if (doAnimation) {
8815 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8816 }
8817 if (requestAnim) {
8818 requestAnimationLocked(0);
8819 }
8820 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 }
8822
8823 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008824 return hideLw(doAnimation, true);
8825 }
8826
8827 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008828 if (doAnimation) {
8829 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8830 doAnimation = false;
8831 }
8832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008833 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8834 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008835 if (!current) {
8836 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008837 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008838 if (doAnimation) {
8839 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8840 if (mAnimation == null) {
8841 doAnimation = false;
8842 }
8843 }
8844 if (doAnimation) {
8845 mPolicyVisibilityAfterAnim = false;
8846 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008847 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008848 mPolicyVisibilityAfterAnim = false;
8849 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008850 // Window is no longer visible -- make sure if we were waiting
8851 // for it to be displayed before enabling the display, that
8852 // we allow the display to be enabled now.
8853 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008854 if (mCurrentFocus == this) {
8855 mFocusMayChange = true;
8856 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008857 }
8858 if (requestAnim) {
8859 requestAnimationLocked(0);
8860 }
8861 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008862 }
8863
8864 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008865 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8866 pw.print(" mClient="); pw.println(mClient.asBinder());
8867 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8868 if (mAttachedWindow != null || mLayoutAttached) {
8869 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8870 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8871 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008872 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8873 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8874 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008875 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8876 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008877 }
8878 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8879 pw.print(" mSubLayer="); pw.print(mSubLayer);
8880 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8881 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8882 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8883 pw.print("="); pw.print(mAnimLayer);
8884 pw.print(" mLastLayer="); pw.println(mLastLayer);
8885 if (mSurface != null) {
8886 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008887 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8888 pw.print(" layer="); pw.print(mSurfaceLayer);
8889 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8890 pw.print(" rect=("); pw.print(mSurfaceX);
8891 pw.print(","); pw.print(mSurfaceY);
8892 pw.print(") "); pw.print(mSurfaceW);
8893 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008894 }
8895 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8896 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8897 if (mAppToken != null) {
8898 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8899 }
8900 if (mTargetAppToken != null) {
8901 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8902 }
8903 pw.print(prefix); pw.print("mViewVisibility=0x");
8904 pw.print(Integer.toHexString(mViewVisibility));
8905 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008906 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8907 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008908 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8909 pw.print(prefix); pw.print("mPolicyVisibility=");
8910 pw.print(mPolicyVisibility);
8911 pw.print(" mPolicyVisibilityAfterAnim=");
8912 pw.print(mPolicyVisibilityAfterAnim);
8913 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8914 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008915 if (!mRelayoutCalled) {
8916 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8917 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008918 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008919 pw.print(" h="); pw.print(mRequestedHeight);
8920 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008921 if (mXOffset != 0 || mYOffset != 0) {
8922 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8923 pw.print(" y="); pw.println(mYOffset);
8924 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008925 pw.print(prefix); pw.print("mGivenContentInsets=");
8926 mGivenContentInsets.printShortString(pw);
8927 pw.print(" mGivenVisibleInsets=");
8928 mGivenVisibleInsets.printShortString(pw);
8929 pw.println();
8930 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8931 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8932 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8933 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008934 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008935 pw.print(prefix); pw.print("mShownFrame=");
8936 mShownFrame.printShortString(pw);
8937 pw.print(" last="); mLastShownFrame.printShortString(pw);
8938 pw.println();
8939 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8940 pw.print(" last="); mLastFrame.printShortString(pw);
8941 pw.println();
8942 pw.print(prefix); pw.print("mContainingFrame=");
8943 mContainingFrame.printShortString(pw);
8944 pw.print(" mDisplayFrame=");
8945 mDisplayFrame.printShortString(pw);
8946 pw.println();
8947 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8948 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8949 pw.println();
8950 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8951 pw.print(" last="); mLastContentInsets.printShortString(pw);
8952 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8953 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8954 pw.println();
8955 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8956 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8957 pw.print(" mAlpha="); pw.print(mAlpha);
8958 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8959 }
8960 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8961 || mAnimation != null) {
8962 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8963 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8964 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8965 pw.print(" mAnimation="); pw.println(mAnimation);
8966 }
8967 if (mHasTransformation || mHasLocalTransformation) {
8968 pw.print(prefix); pw.print("XForm: has=");
8969 pw.print(mHasTransformation);
8970 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8971 pw.print(" "); mTransformation.printShortString(pw);
8972 pw.println();
8973 }
8974 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8975 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8976 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8977 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8978 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8979 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8980 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8981 pw.print(" mDestroying="); pw.print(mDestroying);
8982 pw.print(" mRemoved="); pw.println(mRemoved);
8983 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008984 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008985 pw.print(prefix); pw.print("mOrientationChanging=");
8986 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008987 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8988 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008989 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008990 if (mHScale != 1 || mVScale != 1) {
8991 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8992 pw.print(" mVScale="); pw.println(mVScale);
8993 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008994 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008995 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8996 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8997 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008998 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8999 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
9000 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
9001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009002 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07009003
9004 String makeInputChannelName() {
9005 return Integer.toHexString(System.identityHashCode(this))
9006 + " " + mAttrs.getTitle();
9007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008
9009 @Override
9010 public String toString() {
9011 return "Window{"
9012 + Integer.toHexString(System.identityHashCode(this))
9013 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
9014 }
9015 }
Romain Guy06882f82009-06-10 13:36:04 -07009016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009017 // -------------------------------------------------------------
9018 // Window Token State
9019 // -------------------------------------------------------------
9020
9021 class WindowToken {
9022 // The actual token.
9023 final IBinder token;
9024
9025 // The type of window this token is for, as per WindowManager.LayoutParams.
9026 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07009027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 // Set if this token was explicitly added by a client, so should
9029 // not be removed when all windows are removed.
9030 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07009031
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009032 // For printing.
9033 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07009034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 // If this is an AppWindowToken, this is non-null.
9036 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07009037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038 // All of the windows associated with this token.
9039 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
9040
9041 // Is key dispatching paused for this token?
9042 boolean paused = false;
9043
9044 // Should this token's windows be hidden?
9045 boolean hidden;
9046
9047 // Temporary for finding which tokens no longer have visible windows.
9048 boolean hasVisible;
9049
Dianne Hackborna8f60182009-09-01 19:01:50 -07009050 // Set to true when this token is in a pending transaction where it
9051 // will be shown.
9052 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009053
Dianne Hackborna8f60182009-09-01 19:01:50 -07009054 // Set to true when this token is in a pending transaction where it
9055 // will be hidden.
9056 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009057
Dianne Hackborna8f60182009-09-01 19:01:50 -07009058 // Set to true when this token is in a pending transaction where its
9059 // windows will be put to the bottom of the list.
9060 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009061
Dianne Hackborna8f60182009-09-01 19:01:50 -07009062 // Set to true when this token is in a pending transaction where its
9063 // windows will be put to the top of the list.
9064 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009066 WindowToken(IBinder _token, int type, boolean _explicit) {
9067 token = _token;
9068 windowType = type;
9069 explicit = _explicit;
9070 }
9071
9072 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009073 pw.print(prefix); pw.print("token="); pw.println(token);
9074 pw.print(prefix); pw.print("windows="); pw.println(windows);
9075 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
9076 pw.print(" hidden="); pw.print(hidden);
9077 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009078 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
9079 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
9080 pw.print(" waitingToHide="); pw.print(waitingToHide);
9081 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
9082 pw.print(" sendingToTop="); pw.println(sendingToTop);
9083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 }
9085
9086 @Override
9087 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009088 if (stringName == null) {
9089 StringBuilder sb = new StringBuilder();
9090 sb.append("WindowToken{");
9091 sb.append(Integer.toHexString(System.identityHashCode(this)));
9092 sb.append(" token="); sb.append(token); sb.append('}');
9093 stringName = sb.toString();
9094 }
9095 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009096 }
9097 };
9098
9099 class AppWindowToken extends WindowToken {
9100 // Non-null only for application tokens.
9101 final IApplicationToken appToken;
9102
9103 // All of the windows and child windows that are included in this
9104 // application token. Note this list is NOT sorted!
9105 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
9106
9107 int groupId = -1;
9108 boolean appFullscreen;
9109 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07009110
9111 // The input dispatching timeout for this application token in nanoseconds.
9112 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07009113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 // These are used for determining when all windows associated with
9115 // an activity have been drawn, so they can be made visible together
9116 // at the same time.
9117 int lastTransactionSequence = mTransactionSequence-1;
9118 int numInterestingWindows;
9119 int numDrawnWindows;
9120 boolean inPendingTransaction;
9121 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07009122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009123 // Is this token going to be hidden in a little while? If so, it
9124 // won't be taken into account for setting the screen orientation.
9125 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07009126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009127 // Is this window's surface needed? This is almost like hidden, except
9128 // it will sometimes be true a little earlier: when the token has
9129 // been shown, but is still waiting for its app transition to execute
9130 // before making its windows shown.
9131 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07009132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009133 // Have we told the window clients to hide themselves?
9134 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07009135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009136 // Last visibility state we reported to the app token.
9137 boolean reportedVisible;
9138
9139 // Set to true when the token has been removed from the window mgr.
9140 boolean removed;
9141
9142 // Have we been asked to have this token keep the screen frozen?
9143 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07009144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009145 boolean animating;
9146 Animation animation;
9147 boolean hasTransformation;
9148 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07009149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009150 // Offset to the window of all layers in the token, for use by
9151 // AppWindowToken animations.
9152 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07009153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 // Information about an application starting window if displayed.
9155 StartingData startingData;
9156 WindowState startingWindow;
9157 View startingView;
9158 boolean startingDisplayed;
9159 boolean startingMoved;
9160 boolean firstWindowDrawn;
9161
9162 AppWindowToken(IApplicationToken _token) {
9163 super(_token.asBinder(),
9164 WindowManager.LayoutParams.TYPE_APPLICATION, true);
9165 appWindowToken = this;
9166 appToken = _token;
9167 }
Romain Guy06882f82009-06-10 13:36:04 -07009168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009169 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009170 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009171 TAG, "Setting animation in " + this + ": " + anim);
9172 animation = anim;
9173 animating = false;
9174 anim.restrictDuration(MAX_ANIMATION_DURATION);
9175 anim.scaleCurrentDuration(mTransitionAnimationScale);
9176 int zorder = anim.getZAdjustment();
9177 int adj = 0;
9178 if (zorder == Animation.ZORDER_TOP) {
9179 adj = TYPE_LAYER_OFFSET;
9180 } else if (zorder == Animation.ZORDER_BOTTOM) {
9181 adj = -TYPE_LAYER_OFFSET;
9182 }
Romain Guy06882f82009-06-10 13:36:04 -07009183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 if (animLayerAdjustment != adj) {
9185 animLayerAdjustment = adj;
9186 updateLayers();
9187 }
9188 }
Romain Guy06882f82009-06-10 13:36:04 -07009189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009190 public void setDummyAnimation() {
9191 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009192 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009193 TAG, "Setting dummy animation in " + this);
9194 animation = sDummyAnimation;
9195 }
9196 }
9197
9198 public void clearAnimation() {
9199 if (animation != null) {
9200 animation = null;
9201 animating = true;
9202 }
9203 }
Romain Guy06882f82009-06-10 13:36:04 -07009204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009205 void updateLayers() {
9206 final int N = allAppWindows.size();
9207 final int adj = animLayerAdjustment;
9208 for (int i=0; i<N; i++) {
9209 WindowState w = allAppWindows.get(i);
9210 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009211 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 + w.mAnimLayer);
9213 if (w == mInputMethodTarget) {
9214 setInputMethodAnimLayerAdjustment(adj);
9215 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009216 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07009217 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009219 }
9220 }
Romain Guy06882f82009-06-10 13:36:04 -07009221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 void sendAppVisibilityToClients() {
9223 final int N = allAppWindows.size();
9224 for (int i=0; i<N; i++) {
9225 WindowState win = allAppWindows.get(i);
9226 if (win == startingWindow && clientHidden) {
9227 // Don't hide the starting window.
9228 continue;
9229 }
9230 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009231 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009232 "Setting visibility of " + win + ": " + (!clientHidden));
9233 win.mClient.dispatchAppVisibility(!clientHidden);
9234 } catch (RemoteException e) {
9235 }
9236 }
9237 }
Romain Guy06882f82009-06-10 13:36:04 -07009238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009239 void showAllWindowsLocked() {
9240 final int NW = allAppWindows.size();
9241 for (int i=0; i<NW; i++) {
9242 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009243 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 "performing show on: " + w);
9245 w.performShowLocked();
9246 }
9247 }
Romain Guy06882f82009-06-10 13:36:04 -07009248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 // This must be called while inside a transaction.
9250 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009251 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07009253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 if (animation == sDummyAnimation) {
9255 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009256 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009257 // when it is really time to animate, this will be set to
9258 // a real animation and the next call will execute normally.
9259 return false;
9260 }
Romain Guy06882f82009-06-10 13:36:04 -07009261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009262 if ((allDrawn || animating || startingDisplayed) && animation != null) {
9263 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009264 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 TAG, "Starting animation in " + this +
9266 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
9267 + " scale=" + mTransitionAnimationScale
9268 + " allDrawn=" + allDrawn + " animating=" + animating);
9269 animation.initialize(dw, dh, dw, dh);
9270 animation.setStartTime(currentTime);
9271 animating = true;
9272 }
9273 transformation.clear();
9274 final boolean more = animation.getTransformation(
9275 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009276 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 TAG, "Stepped animation in " + this +
9278 ": more=" + more + ", xform=" + transformation);
9279 if (more) {
9280 // we're done!
9281 hasTransformation = true;
9282 return true;
9283 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009284 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009285 TAG, "Finished animation in " + this +
9286 " @ " + currentTime);
9287 animation = null;
9288 }
9289 } else if (animation != null) {
9290 // If the display is frozen, and there is a pending animation,
9291 // clear it and make sure we run the cleanup code.
9292 animating = true;
9293 animation = null;
9294 }
9295
9296 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07009297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009298 if (!animating) {
9299 return false;
9300 }
9301
9302 clearAnimation();
9303 animating = false;
9304 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
9305 moveInputMethodWindowsIfNeededLocked(true);
9306 }
Romain Guy06882f82009-06-10 13:36:04 -07009307
Joe Onorato8a9b2202010-02-26 18:56:32 -08009308 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 TAG, "Animation done in " + this
9310 + ": reportedVisible=" + reportedVisible);
9311
9312 transformation.clear();
9313 if (animLayerAdjustment != 0) {
9314 animLayerAdjustment = 0;
9315 updateLayers();
9316 }
Romain Guy06882f82009-06-10 13:36:04 -07009317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 final int N = windows.size();
9319 for (int i=0; i<N; i++) {
9320 ((WindowState)windows.get(i)).finishExit();
9321 }
9322 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07009323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 return false;
9325 }
9326
9327 void updateReportedVisibilityLocked() {
9328 if (appToken == null) {
9329 return;
9330 }
Romain Guy06882f82009-06-10 13:36:04 -07009331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009332 int numInteresting = 0;
9333 int numVisible = 0;
9334 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07009335
Joe Onorato8a9b2202010-02-26 18:56:32 -08009336 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009337 final int N = allAppWindows.size();
9338 for (int i=0; i<N; i++) {
9339 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08009340 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07009341 || win.mViewVisibility != View.VISIBLE
9342 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009343 continue;
9344 }
9345 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009346 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009347 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009348 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009349 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009350 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 + " pv=" + win.mPolicyVisibility
9352 + " dp=" + win.mDrawPending
9353 + " cdp=" + win.mCommitDrawPending
9354 + " ah=" + win.mAttachedHidden
9355 + " th="
9356 + (win.mAppToken != null
9357 ? win.mAppToken.hiddenRequested : false)
9358 + " a=" + win.mAnimating);
9359 }
9360 }
9361 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009362 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 if (!win.isAnimating()) {
9364 numVisible++;
9365 }
9366 nowGone = false;
9367 } else if (win.isAnimating()) {
9368 nowGone = false;
9369 }
9370 }
Romain Guy06882f82009-06-10 13:36:04 -07009371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009372 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009373 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 + numInteresting + " visible=" + numVisible);
9375 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009376 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377 TAG, "Visibility changed in " + this
9378 + ": vis=" + nowVisible);
9379 reportedVisible = nowVisible;
9380 Message m = mH.obtainMessage(
9381 H.REPORT_APPLICATION_TOKEN_WINDOWS,
9382 nowVisible ? 1 : 0,
9383 nowGone ? 1 : 0,
9384 this);
9385 mH.sendMessage(m);
9386 }
9387 }
Romain Guy06882f82009-06-10 13:36:04 -07009388
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009389 WindowState findMainWindow() {
9390 int j = windows.size();
9391 while (j > 0) {
9392 j--;
9393 WindowState win = windows.get(j);
9394 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
9395 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
9396 return win;
9397 }
9398 }
9399 return null;
9400 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009402 void dump(PrintWriter pw, String prefix) {
9403 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009404 if (appToken != null) {
9405 pw.print(prefix); pw.println("app=true");
9406 }
9407 if (allAppWindows.size() > 0) {
9408 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
9409 }
9410 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009411 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009412 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
9413 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
9414 pw.print(" clientHidden="); pw.print(clientHidden);
9415 pw.print(" willBeHidden="); pw.print(willBeHidden);
9416 pw.print(" reportedVisible="); pw.println(reportedVisible);
9417 if (paused || freezingScreen) {
9418 pw.print(prefix); pw.print("paused="); pw.print(paused);
9419 pw.print(" freezingScreen="); pw.println(freezingScreen);
9420 }
9421 if (numInterestingWindows != 0 || numDrawnWindows != 0
9422 || inPendingTransaction || allDrawn) {
9423 pw.print(prefix); pw.print("numInterestingWindows=");
9424 pw.print(numInterestingWindows);
9425 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
9426 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
9427 pw.print(" allDrawn="); pw.println(allDrawn);
9428 }
9429 if (animating || animation != null) {
9430 pw.print(prefix); pw.print("animating="); pw.print(animating);
9431 pw.print(" animation="); pw.println(animation);
9432 }
9433 if (animLayerAdjustment != 0) {
9434 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
9435 }
9436 if (hasTransformation) {
9437 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
9438 pw.print(" transformation="); transformation.printShortString(pw);
9439 pw.println();
9440 }
9441 if (startingData != null || removed || firstWindowDrawn) {
9442 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
9443 pw.print(" removed="); pw.print(removed);
9444 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
9445 }
9446 if (startingWindow != null || startingView != null
9447 || startingDisplayed || startingMoved) {
9448 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
9449 pw.print(" startingView="); pw.print(startingView);
9450 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
9451 pw.print(" startingMoved"); pw.println(startingMoved);
9452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 }
9454
9455 @Override
9456 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009457 if (stringName == null) {
9458 StringBuilder sb = new StringBuilder();
9459 sb.append("AppWindowToken{");
9460 sb.append(Integer.toHexString(System.identityHashCode(this)));
9461 sb.append(" token="); sb.append(token); sb.append('}');
9462 stringName = sb.toString();
9463 }
9464 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009465 }
9466 }
Romain Guy06882f82009-06-10 13:36:04 -07009467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009468 // -------------------------------------------------------------
9469 // DummyAnimation
9470 // -------------------------------------------------------------
9471
9472 // This is an animation that does nothing: it just immediately finishes
9473 // itself every time it is called. It is used as a stub animation in cases
9474 // where we want to synchronize multiple things that may be animating.
9475 static final class DummyAnimation extends Animation {
9476 public boolean getTransformation(long currentTime, Transformation outTransformation) {
9477 return false;
9478 }
9479 }
9480 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07009481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009482 // -------------------------------------------------------------
9483 // Async Handler
9484 // -------------------------------------------------------------
9485
9486 static final class StartingData {
9487 final String pkg;
9488 final int theme;
9489 final CharSequence nonLocalizedLabel;
9490 final int labelRes;
9491 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07009492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009493 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
9494 int _labelRes, int _icon) {
9495 pkg = _pkg;
9496 theme = _theme;
9497 nonLocalizedLabel = _nonLocalizedLabel;
9498 labelRes = _labelRes;
9499 icon = _icon;
9500 }
9501 }
9502
9503 private final class H extends Handler {
9504 public static final int REPORT_FOCUS_CHANGE = 2;
9505 public static final int REPORT_LOSING_FOCUS = 3;
9506 public static final int ANIMATE = 4;
9507 public static final int ADD_STARTING = 5;
9508 public static final int REMOVE_STARTING = 6;
9509 public static final int FINISHED_STARTING = 7;
9510 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009511 public static final int WINDOW_FREEZE_TIMEOUT = 11;
9512 public static final int HOLD_SCREEN_CHANGED = 12;
9513 public static final int APP_TRANSITION_TIMEOUT = 13;
9514 public static final int PERSIST_ANIMATION_SCALE = 14;
9515 public static final int FORCE_GC = 15;
9516 public static final int ENABLE_SCREEN = 16;
9517 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009518 public static final int SEND_NEW_CONFIGURATION = 18;
Romain Guy06882f82009-06-10 13:36:04 -07009519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009520 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07009521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 public H() {
9523 }
Romain Guy06882f82009-06-10 13:36:04 -07009524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 @Override
9526 public void handleMessage(Message msg) {
9527 switch (msg.what) {
9528 case REPORT_FOCUS_CHANGE: {
9529 WindowState lastFocus;
9530 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07009531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 synchronized(mWindowMap) {
9533 lastFocus = mLastFocus;
9534 newFocus = mCurrentFocus;
9535 if (lastFocus == newFocus) {
9536 // Focus is not changing, so nothing to do.
9537 return;
9538 }
9539 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009540 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 // + " to " + newFocus);
9542 if (newFocus != null && lastFocus != null
9543 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009544 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009545 mLosingFocus.add(lastFocus);
9546 lastFocus = null;
9547 }
9548 }
9549
9550 if (lastFocus != newFocus) {
9551 //System.out.println("Changing focus from " + lastFocus
9552 // + " to " + newFocus);
9553 if (newFocus != null) {
9554 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009555 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009556 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
9557 } catch (RemoteException e) {
9558 // Ignore if process has died.
9559 }
9560 }
9561
9562 if (lastFocus != null) {
9563 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009564 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
9566 } catch (RemoteException e) {
9567 // Ignore if process has died.
9568 }
9569 }
9570 }
9571 } break;
9572
9573 case REPORT_LOSING_FOCUS: {
9574 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07009575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576 synchronized(mWindowMap) {
9577 losers = mLosingFocus;
9578 mLosingFocus = new ArrayList<WindowState>();
9579 }
9580
9581 final int N = losers.size();
9582 for (int i=0; i<N; i++) {
9583 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009584 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009585 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
9586 } catch (RemoteException e) {
9587 // Ignore if process has died.
9588 }
9589 }
9590 } break;
9591
9592 case ANIMATE: {
9593 synchronized(mWindowMap) {
9594 mAnimationPending = false;
9595 performLayoutAndPlaceSurfacesLocked();
9596 }
9597 } break;
9598
9599 case ADD_STARTING: {
9600 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9601 final StartingData sd = wtoken.startingData;
9602
9603 if (sd == null) {
9604 // Animation has been canceled... do nothing.
9605 return;
9606 }
Romain Guy06882f82009-06-10 13:36:04 -07009607
Joe Onorato8a9b2202010-02-26 18:56:32 -08009608 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009609 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07009610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009611 View view = null;
9612 try {
9613 view = mPolicy.addStartingWindow(
9614 wtoken.token, sd.pkg,
9615 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
9616 sd.icon);
9617 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009618 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009619 }
9620
9621 if (view != null) {
9622 boolean abort = false;
9623
9624 synchronized(mWindowMap) {
9625 if (wtoken.removed || wtoken.startingData == null) {
9626 // If the window was successfully added, then
9627 // we need to remove it.
9628 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009629 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630 "Aborted starting " + wtoken
9631 + ": removed=" + wtoken.removed
9632 + " startingData=" + wtoken.startingData);
9633 wtoken.startingWindow = null;
9634 wtoken.startingData = null;
9635 abort = true;
9636 }
9637 } else {
9638 wtoken.startingView = view;
9639 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009640 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009641 "Added starting " + wtoken
9642 + ": startingWindow="
9643 + wtoken.startingWindow + " startingView="
9644 + wtoken.startingView);
9645 }
9646
9647 if (abort) {
9648 try {
9649 mPolicy.removeStartingWindow(wtoken.token, view);
9650 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009651 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 }
9653 }
9654 }
9655 } break;
9656
9657 case REMOVE_STARTING: {
9658 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9659 IBinder token = null;
9660 View view = null;
9661 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009662 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009663 + wtoken + ": startingWindow="
9664 + wtoken.startingWindow + " startingView="
9665 + wtoken.startingView);
9666 if (wtoken.startingWindow != null) {
9667 view = wtoken.startingView;
9668 token = wtoken.token;
9669 wtoken.startingData = null;
9670 wtoken.startingView = null;
9671 wtoken.startingWindow = null;
9672 }
9673 }
9674 if (view != null) {
9675 try {
9676 mPolicy.removeStartingWindow(token, view);
9677 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009678 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009679 }
9680 }
9681 } break;
9682
9683 case FINISHED_STARTING: {
9684 IBinder token = null;
9685 View view = null;
9686 while (true) {
9687 synchronized (mWindowMap) {
9688 final int N = mFinishedStarting.size();
9689 if (N <= 0) {
9690 break;
9691 }
9692 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9693
Joe Onorato8a9b2202010-02-26 18:56:32 -08009694 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 "Finished starting " + wtoken
9696 + ": startingWindow=" + wtoken.startingWindow
9697 + " startingView=" + wtoken.startingView);
9698
9699 if (wtoken.startingWindow == null) {
9700 continue;
9701 }
9702
9703 view = wtoken.startingView;
9704 token = wtoken.token;
9705 wtoken.startingData = null;
9706 wtoken.startingView = null;
9707 wtoken.startingWindow = null;
9708 }
9709
9710 try {
9711 mPolicy.removeStartingWindow(token, view);
9712 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009713 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009714 }
9715 }
9716 } break;
9717
9718 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9719 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9720
9721 boolean nowVisible = msg.arg1 != 0;
9722 boolean nowGone = msg.arg2 != 0;
9723
9724 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009725 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009726 TAG, "Reporting visible in " + wtoken
9727 + " visible=" + nowVisible
9728 + " gone=" + nowGone);
9729 if (nowVisible) {
9730 wtoken.appToken.windowsVisible();
9731 } else {
9732 wtoken.appToken.windowsGone();
9733 }
9734 } catch (RemoteException ex) {
9735 }
9736 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 case WINDOW_FREEZE_TIMEOUT: {
9739 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009740 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 int i = mWindows.size();
9742 while (i > 0) {
9743 i--;
9744 WindowState w = (WindowState)mWindows.get(i);
9745 if (w.mOrientationChanging) {
9746 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009747 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 }
9749 }
9750 performLayoutAndPlaceSurfacesLocked();
9751 }
9752 break;
9753 }
Romain Guy06882f82009-06-10 13:36:04 -07009754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 case HOLD_SCREEN_CHANGED: {
9756 Session oldHold;
9757 Session newHold;
9758 synchronized (mWindowMap) {
9759 oldHold = mLastReportedHold;
9760 newHold = (Session)msg.obj;
9761 mLastReportedHold = newHold;
9762 }
Romain Guy06882f82009-06-10 13:36:04 -07009763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 if (oldHold != newHold) {
9765 try {
9766 if (oldHold != null) {
9767 mBatteryStats.noteStopWakelock(oldHold.mUid,
9768 "window",
9769 BatteryStats.WAKE_TYPE_WINDOW);
9770 }
9771 if (newHold != null) {
9772 mBatteryStats.noteStartWakelock(newHold.mUid,
9773 "window",
9774 BatteryStats.WAKE_TYPE_WINDOW);
9775 }
9776 } catch (RemoteException e) {
9777 }
9778 }
9779 break;
9780 }
Romain Guy06882f82009-06-10 13:36:04 -07009781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009782 case APP_TRANSITION_TIMEOUT: {
9783 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009784 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009785 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009786 "*** APP TRANSITION TIMEOUT");
9787 mAppTransitionReady = true;
9788 mAppTransitionTimeout = true;
9789 performLayoutAndPlaceSurfacesLocked();
9790 }
9791 }
9792 break;
9793 }
Romain Guy06882f82009-06-10 13:36:04 -07009794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009795 case PERSIST_ANIMATION_SCALE: {
9796 Settings.System.putFloat(mContext.getContentResolver(),
9797 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9798 Settings.System.putFloat(mContext.getContentResolver(),
9799 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9800 break;
9801 }
Romain Guy06882f82009-06-10 13:36:04 -07009802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 case FORCE_GC: {
9804 synchronized(mWindowMap) {
9805 if (mAnimationPending) {
9806 // If we are animating, don't do the gc now but
9807 // delay a bit so we don't interrupt the animation.
9808 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9809 2000);
9810 return;
9811 }
9812 // If we are currently rotating the display, it will
9813 // schedule a new message when done.
9814 if (mDisplayFrozen) {
9815 return;
9816 }
9817 mFreezeGcPending = 0;
9818 }
9819 Runtime.getRuntime().gc();
9820 break;
9821 }
Romain Guy06882f82009-06-10 13:36:04 -07009822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009823 case ENABLE_SCREEN: {
9824 performEnableScreen();
9825 break;
9826 }
Romain Guy06882f82009-06-10 13:36:04 -07009827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 case APP_FREEZE_TIMEOUT: {
9829 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009830 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 int i = mAppTokens.size();
9832 while (i > 0) {
9833 i--;
9834 AppWindowToken tok = mAppTokens.get(i);
9835 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009836 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009837 unsetAppFreezingScreenLocked(tok, true, true);
9838 }
9839 }
9840 }
9841 break;
9842 }
Romain Guy06882f82009-06-10 13:36:04 -07009843
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009844 case SEND_NEW_CONFIGURATION: {
9845 removeMessages(SEND_NEW_CONFIGURATION);
9846 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009847 break;
9848 }
Romain Guy06882f82009-06-10 13:36:04 -07009849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009850 }
9851 }
9852 }
9853
9854 // -------------------------------------------------------------
9855 // IWindowManager API
9856 // -------------------------------------------------------------
9857
9858 public IWindowSession openSession(IInputMethodClient client,
9859 IInputContext inputContext) {
9860 if (client == null) throw new IllegalArgumentException("null client");
9861 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac02010-04-22 18:58:52 -07009862 Session session = new Session(client, inputContext);
9863 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 }
9865
9866 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9867 synchronized (mWindowMap) {
9868 // The focus for the client is the window immediately below
9869 // where we would place the input method window.
9870 int idx = findDesiredInputMethodWindowIndexLocked(false);
9871 WindowState imFocus;
9872 if (idx > 0) {
9873 imFocus = (WindowState)mWindows.get(idx-1);
9874 if (imFocus != null) {
9875 if (imFocus.mSession.mClient != null &&
9876 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9877 return true;
9878 }
9879 }
9880 }
9881 }
9882 return false;
9883 }
Romain Guy06882f82009-06-10 13:36:04 -07009884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009885 // -------------------------------------------------------------
9886 // Internals
9887 // -------------------------------------------------------------
9888
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009889 final WindowState windowForClientLocked(Session session, IWindow client,
9890 boolean throwOnError) {
9891 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 }
Romain Guy06882f82009-06-10 13:36:04 -07009893
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009894 final WindowState windowForClientLocked(Session session, IBinder client,
9895 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009896 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009897 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 TAG, "Looking up client " + client + ": " + win);
9899 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009900 RuntimeException ex = new IllegalArgumentException(
9901 "Requested window " + client + " does not exist");
9902 if (throwOnError) {
9903 throw ex;
9904 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009905 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 return null;
9907 }
9908 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009909 RuntimeException ex = new IllegalArgumentException(
9910 "Requested window " + client + " is in session " +
9911 win.mSession + ", not " + session);
9912 if (throwOnError) {
9913 throw ex;
9914 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009915 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 return null;
9917 }
9918
9919 return win;
9920 }
9921
Dianne Hackborna8f60182009-09-01 19:01:50 -07009922 final void rebuildAppWindowListLocked() {
9923 int NW = mWindows.size();
9924 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009925 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009926 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009927
Dianne Hackborna8f60182009-09-01 19:01:50 -07009928 // First remove all existing app windows.
9929 i=0;
9930 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009931 WindowState w = (WindowState)mWindows.get(i);
9932 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009933 WindowState win = (WindowState)mWindows.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009934 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009935 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009936 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009937 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009938 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009939 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9940 && lastWallpaper == i-1) {
9941 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009942 }
9943 i++;
9944 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009945
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009946 // The wallpaper window(s) typically live at the bottom of the stack,
9947 // so skip them before adding app tokens.
9948 lastWallpaper++;
9949 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009950
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009951 // First add all of the exiting app tokens... these are no longer
9952 // in the main app list, but still have windows shown. We put them
9953 // in the back because now that the animation is over we no longer
9954 // will care about them.
9955 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009956 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009957 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9958 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009959
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009960 // And add in the still active app tokens in Z order.
9961 NT = mAppTokens.size();
9962 for (int j=0; j<NT; j++) {
9963 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009964 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009965
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009966 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009967 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009968 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009969 + " windows but added " + i);
9970 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009971 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973 private final void assignLayersLocked() {
9974 int N = mWindows.size();
9975 int curBaseLayer = 0;
9976 int curLayer = 0;
9977 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 for (i=0; i<N; i++) {
9980 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009981 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9982 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009983 curLayer += WINDOW_LAYER_MULTIPLIER;
9984 w.mLayer = curLayer;
9985 } else {
9986 curBaseLayer = curLayer = w.mBaseLayer;
9987 w.mLayer = curLayer;
9988 }
9989 if (w.mTargetAppToken != null) {
9990 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9991 } else if (w.mAppToken != null) {
9992 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9993 } else {
9994 w.mAnimLayer = w.mLayer;
9995 }
9996 if (w.mIsImWindow) {
9997 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009998 } else if (w.mIsWallpaper) {
9999 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010001 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010002 + w.mAnimLayer);
10003 //System.out.println(
10004 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
10005 }
10006 }
10007
10008 private boolean mInLayout = false;
10009 private final void performLayoutAndPlaceSurfacesLocked() {
10010 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -070010011 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 throw new RuntimeException("Recursive call!");
10013 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010014 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 return;
10016 }
10017
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010018 if (mWaitingForConfig) {
10019 // Our configuration has changed (most likely rotation), but we
10020 // don't yet have the complete configuration to report to
10021 // applications. Don't do any window layout until we have it.
10022 return;
10023 }
10024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 boolean recoveringMemory = false;
10026 if (mForceRemoves != null) {
10027 recoveringMemory = true;
10028 // Wait a little it for things to settle down, and off we go.
10029 for (int i=0; i<mForceRemoves.size(); i++) {
10030 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010031 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010032 removeWindowInnerLocked(ws.mSession, ws);
10033 }
10034 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010035 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 Object tmp = new Object();
10037 synchronized (tmp) {
10038 try {
10039 tmp.wait(250);
10040 } catch (InterruptedException e) {
10041 }
10042 }
10043 }
Romain Guy06882f82009-06-10 13:36:04 -070010044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010045 mInLayout = true;
10046 try {
10047 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -070010048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 int i = mPendingRemove.size()-1;
10050 if (i >= 0) {
10051 while (i >= 0) {
10052 WindowState w = mPendingRemove.get(i);
10053 removeWindowInnerLocked(w.mSession, w);
10054 i--;
10055 }
10056 mPendingRemove.clear();
10057
10058 mInLayout = false;
10059 assignLayersLocked();
10060 mLayoutNeeded = true;
10061 performLayoutAndPlaceSurfacesLocked();
10062
10063 } else {
10064 mInLayout = false;
10065 if (mLayoutNeeded) {
10066 requestAnimationLocked(0);
10067 }
10068 }
10069 } catch (RuntimeException e) {
10070 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010071 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 }
10073 }
10074
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010075 private final int performLayoutLockedInner() {
10076 if (!mLayoutNeeded) {
10077 return 0;
10078 }
10079
10080 mLayoutNeeded = false;
10081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010082 final int dw = mDisplay.getWidth();
10083 final int dh = mDisplay.getHeight();
10084
10085 final int N = mWindows.size();
10086 int i;
10087
Joe Onorato8a9b2202010-02-26 18:56:32 -080010088 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -080010089 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
10090
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010091 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -070010092
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010093 int seq = mLayoutSeq+1;
10094 if (seq < 0) seq = 0;
10095 mLayoutSeq = seq;
10096
10097 // First perform layout of any root windows (not attached
10098 // to another window).
10099 int topAttached = -1;
10100 for (i = N-1; i >= 0; i--) {
10101 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010103 // Don't do layout of a window if it is not visible, or
10104 // soon won't be visible, to avoid wasting time and funky
10105 // changes while a window is animating away.
10106 final AppWindowToken atoken = win.mAppToken;
10107 final boolean gone = win.mViewVisibility == View.GONE
10108 || !win.mRelayoutCalled
10109 || win.mRootToken.hidden
10110 || (atoken != null && atoken.hiddenRequested)
10111 || win.mAttachedHidden
10112 || win.mExiting || win.mDestroying;
10113
10114 if (!win.mLayoutAttached) {
10115 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
10116 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
10117 + " mLayoutAttached=" + win.mLayoutAttached);
10118 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
10119 + win.mViewVisibility + " mRelayoutCalled="
10120 + win.mRelayoutCalled + " hidden="
10121 + win.mRootToken.hidden + " hiddenRequested="
10122 + (atoken != null && atoken.hiddenRequested)
10123 + " mAttachedHidden=" + win.mAttachedHidden);
10124 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010125
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010126 // If this view is GONE, then skip it -- keep the current
10127 // frame, and let the caller know so they can ignore it
10128 // if they want. (We do the normal layout for INVISIBLE
10129 // windows, since that means "perform layout as normal,
10130 // just don't display").
10131 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010132 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010133 mPolicy.layoutWindowLw(win, win.mAttrs, null);
10134 win.mLayoutSeq = seq;
10135 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
10136 + win.mFrame + " mContainingFrame="
10137 + win.mContainingFrame + " mDisplayFrame="
10138 + win.mDisplayFrame);
10139 } else {
10140 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010141 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -070010142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010144
10145 // Now perform layout of attached windows, which usually
10146 // depend on the position of the window they are attached to.
10147 // XXX does not deal with windows that are attached to windows
10148 // that are themselves attached.
10149 for (i = topAttached; i >= 0; i--) {
10150 WindowState win = (WindowState) mWindows.get(i);
10151
10152 // If this view is GONE, then skip it -- keep the current
10153 // frame, and let the caller know so they can ignore it
10154 // if they want. (We do the normal layout for INVISIBLE
10155 // windows, since that means "perform layout as normal,
10156 // just don't display").
10157 if (win.mLayoutAttached) {
10158 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
10159 + " mHaveFrame=" + win.mHaveFrame
10160 + " mViewVisibility=" + win.mViewVisibility
10161 + " mRelayoutCalled=" + win.mRelayoutCalled);
10162 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
10163 || !win.mHaveFrame) {
10164 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
10165 win.mLayoutSeq = seq;
10166 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
10167 + win.mFrame + " mContainingFrame="
10168 + win.mContainingFrame + " mDisplayFrame="
10169 + win.mDisplayFrame);
10170 }
10171 }
10172 }
Jeff Brown349703e2010-06-22 01:27:15 -070010173
10174 // Window frames may have changed. Tell the input dispatcher about it.
10175 if (ENABLE_NATIVE_INPUT_DISPATCH) {
10176 mInputMonitor.updateInputWindowsLw();
10177 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010178
10179 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 }
Romain Guy06882f82009-06-10 13:36:04 -070010181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 private final void performLayoutAndPlaceSurfacesLockedInner(
10183 boolean recoveringMemory) {
10184 final long currentTime = SystemClock.uptimeMillis();
10185 final int dw = mDisplay.getWidth();
10186 final int dh = mDisplay.getHeight();
10187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 int i;
10189
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010190 if (mFocusMayChange) {
10191 mFocusMayChange = false;
10192 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
10193 }
10194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 if (mFxSession == null) {
10196 mFxSession = new SurfaceSession();
10197 }
Romain Guy06882f82009-06-10 13:36:04 -070010198
Joe Onorato8a9b2202010-02-26 18:56:32 -080010199 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010200
10201 // Initialize state of exiting tokens.
10202 for (i=mExitingTokens.size()-1; i>=0; i--) {
10203 mExitingTokens.get(i).hasVisible = false;
10204 }
10205
10206 // Initialize state of exiting applications.
10207 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10208 mExitingAppTokens.get(i).hasVisible = false;
10209 }
10210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010211 boolean orientationChangeComplete = true;
10212 Session holdScreen = null;
10213 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010214 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010215 boolean focusDisplayed = false;
10216 boolean animating = false;
10217
10218 Surface.openTransaction();
10219 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010220 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010221 int repeats = 0;
10222 int changes = 0;
10223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010224 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010225 repeats++;
10226 if (repeats > 6) {
10227 Slog.w(TAG, "Animation repeat aborted after too many iterations");
10228 mLayoutNeeded = false;
10229 break;
10230 }
10231
10232 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
10233 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
10234 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
10235 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
10236 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
10237 assignLayersLocked();
10238 mLayoutNeeded = true;
10239 }
10240 }
10241 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
10242 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
10243 if (updateOrientationFromAppTokensLocked()) {
10244 mLayoutNeeded = true;
10245 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10246 }
10247 }
10248 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
10249 mLayoutNeeded = true;
10250 }
10251 }
10252
10253 // FIRST LOOP: Perform a layout, if needed.
10254 if (repeats < 4) {
10255 changes = performLayoutLockedInner();
10256 if (changes != 0) {
10257 continue;
10258 }
10259 } else {
10260 Slog.w(TAG, "Layout repeat skipped after too many iterations");
10261 changes = 0;
10262 }
10263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010264 final int transactionSequence = ++mTransactionSequence;
10265
10266 // Update animations of all applications, including those
10267 // associated with exiting/removed apps
10268 boolean tokensAnimating = false;
10269 final int NAT = mAppTokens.size();
10270 for (i=0; i<NAT; i++) {
10271 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10272 tokensAnimating = true;
10273 }
10274 }
10275 final int NEAT = mExitingAppTokens.size();
10276 for (i=0; i<NEAT; i++) {
10277 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10278 tokensAnimating = true;
10279 }
10280 }
10281
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010282 // SECOND LOOP: Execute animations and update visibility of windows.
10283
Joe Onorato8a9b2202010-02-26 18:56:32 -080010284 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010285 + transactionSequence + " tokensAnimating="
10286 + tokensAnimating);
10287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010289
10290 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010291 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010292 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293
10294 mPolicy.beginAnimationLw(dw, dh);
10295
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010296 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 for (i=N-1; i>=0; i--) {
10299 WindowState w = (WindowState)mWindows.get(i);
10300
10301 final WindowManager.LayoutParams attrs = w.mAttrs;
10302
10303 if (w.mSurface != null) {
10304 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010305 if (w.commitFinishDrawingLocked(currentTime)) {
10306 if ((w.mAttrs.flags
10307 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010308 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010309 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010310 wallpaperMayChange = true;
10311 }
10312 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010313
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010314 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010315 if (w.stepAnimationLocked(currentTime, dw, dh)) {
10316 animating = true;
10317 //w.dump(" ");
10318 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010319 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
10320 wallpaperMayChange = true;
10321 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010322
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010323 if (mPolicy.doesForceHide(w, attrs)) {
10324 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010325 if (DEBUG_VISIBILITY) Slog.v(TAG,
10326 "Animation done that could impact force hide: "
10327 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010328 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010329 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010330 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
10331 forceHiding = true;
10332 }
10333 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10334 boolean changed;
10335 if (forceHiding) {
10336 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010337 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10338 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010339 } else {
10340 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010341 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10342 "Now policy shown: " + w);
10343 if (changed) {
10344 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010345 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010346 // Assume we will need to animate. If
10347 // we don't (because the wallpaper will
10348 // stay with the lock screen), then we will
10349 // clean up later.
10350 Animation a = mPolicy.createForceHideEnterAnimation();
10351 if (a != null) {
10352 w.setAnimation(a);
10353 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010354 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010355 if (mCurrentFocus == null ||
10356 mCurrentFocus.mLayer < w.mLayer) {
10357 // We are showing on to of the current
10358 // focus, so re-evaluate focus to make
10359 // sure it is correct.
10360 mFocusMayChange = true;
10361 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010362 }
10363 }
10364 if (changed && (attrs.flags
10365 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
10366 wallpaperMayChange = true;
10367 }
10368 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370 mPolicy.animatingWindowLw(w, attrs);
10371 }
10372
10373 final AppWindowToken atoken = w.mAppToken;
10374 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
10375 if (atoken.lastTransactionSequence != transactionSequence) {
10376 atoken.lastTransactionSequence = transactionSequence;
10377 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
10378 atoken.startingDisplayed = false;
10379 }
10380 if ((w.isOnScreen() || w.mAttrs.type
10381 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
10382 && !w.mExiting && !w.mDestroying) {
10383 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010384 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010385 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010386 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010387 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010388 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010389 + " pv=" + w.mPolicyVisibility
10390 + " dp=" + w.mDrawPending
10391 + " cdp=" + w.mCommitDrawPending
10392 + " ah=" + w.mAttachedHidden
10393 + " th=" + atoken.hiddenRequested
10394 + " a=" + w.mAnimating);
10395 }
10396 }
10397 if (w != atoken.startingWindow) {
10398 if (!atoken.freezingScreen || !w.mAppFreezing) {
10399 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010400 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010401 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010402 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010403 "tokenMayBeDrawn: " + atoken
10404 + " freezingScreen=" + atoken.freezingScreen
10405 + " mAppFreezing=" + w.mAppFreezing);
10406 tokenMayBeDrawn = true;
10407 }
10408 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010409 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010410 atoken.startingDisplayed = true;
10411 }
10412 }
10413 } else if (w.mReadyToShow) {
10414 w.performShowLocked();
10415 }
10416 }
10417
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010418 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010419
10420 if (tokenMayBeDrawn) {
10421 // See if any windows have been drawn, so they (and others
10422 // associated with them) can now be shown.
10423 final int NT = mTokenList.size();
10424 for (i=0; i<NT; i++) {
10425 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
10426 if (wtoken == null) {
10427 continue;
10428 }
10429 if (wtoken.freezingScreen) {
10430 int numInteresting = wtoken.numInterestingWindows;
10431 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010432 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010433 "allDrawn: " + wtoken
10434 + " interesting=" + numInteresting
10435 + " drawn=" + wtoken.numDrawnWindows);
10436 wtoken.showAllWindowsLocked();
10437 unsetAppFreezingScreenLocked(wtoken, false, true);
10438 orientationChangeComplete = true;
10439 }
10440 } else if (!wtoken.allDrawn) {
10441 int numInteresting = wtoken.numInterestingWindows;
10442 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010444 "allDrawn: " + wtoken
10445 + " interesting=" + numInteresting
10446 + " drawn=" + wtoken.numDrawnWindows);
10447 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010448 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449
10450 // We can now show all of the drawn windows!
10451 if (!mOpeningApps.contains(wtoken)) {
10452 wtoken.showAllWindowsLocked();
10453 }
10454 }
10455 }
10456 }
10457 }
10458
10459 // If we are ready to perform an app transition, check through
10460 // all of the app tokens to be shown and see if they are ready
10461 // to go.
10462 if (mAppTransitionReady) {
10463 int NN = mOpeningApps.size();
10464 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010465 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010466 "Checking " + NN + " opening apps (frozen="
10467 + mDisplayFrozen + " timeout="
10468 + mAppTransitionTimeout + ")...");
10469 if (!mDisplayFrozen && !mAppTransitionTimeout) {
10470 // If the display isn't frozen, wait to do anything until
10471 // all of the apps are ready. Otherwise just go because
10472 // we'll unfreeze the display when everyone is ready.
10473 for (i=0; i<NN && goodToGo; i++) {
10474 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010475 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010476 "Check opening app" + wtoken + ": allDrawn="
10477 + wtoken.allDrawn + " startingDisplayed="
10478 + wtoken.startingDisplayed);
10479 if (!wtoken.allDrawn && !wtoken.startingDisplayed
10480 && !wtoken.startingMoved) {
10481 goodToGo = false;
10482 }
10483 }
10484 }
10485 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010486 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010487 int transit = mNextAppTransition;
10488 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010489 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010491 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010492 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010493 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010494 mAppTransitionTimeout = false;
10495 mStartingIconInTransition = false;
10496 mSkipAppTransitionAnimation = false;
10497
10498 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
10499
Dianne Hackborna8f60182009-09-01 19:01:50 -070010500 // If there are applications waiting to come to the
10501 // top of the stack, now is the time to move their windows.
10502 // (Note that we don't do apps going to the bottom
10503 // here -- we want to keep their windows in the old
10504 // Z-order until the animation completes.)
10505 if (mToTopApps.size() > 0) {
10506 NN = mAppTokens.size();
10507 for (i=0; i<NN; i++) {
10508 AppWindowToken wtoken = mAppTokens.get(i);
10509 if (wtoken.sendingToTop) {
10510 wtoken.sendingToTop = false;
10511 moveAppWindowsLocked(wtoken, NN, false);
10512 }
10513 }
10514 mToTopApps.clear();
10515 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010516
Dianne Hackborn25994b42009-09-04 14:21:19 -070010517 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010518
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010519 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010520 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010521
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010522 // The top-most window will supply the layout params,
10523 // and we will determine it below.
10524 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010525 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010526 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010527
Joe Onorato8a9b2202010-02-26 18:56:32 -080010528 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010529 "New wallpaper target=" + mWallpaperTarget
10530 + ", lower target=" + mLowerWallpaperTarget
10531 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -070010532 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010533 // Do a first pass through the tokens for two
10534 // things:
10535 // (1) Determine if both the closing and opening
10536 // app token sets are wallpaper targets, in which
10537 // case special animations are needed
10538 // (since the wallpaper needs to stay static
10539 // behind them).
10540 // (2) Find the layout params of the top-most
10541 // application window in the tokens, which is
10542 // what will control the animation theme.
10543 final int NC = mClosingApps.size();
10544 NN = NC + mOpeningApps.size();
10545 for (i=0; i<NN; i++) {
10546 AppWindowToken wtoken;
10547 int mode;
10548 if (i < NC) {
10549 wtoken = mClosingApps.get(i);
10550 mode = 1;
10551 } else {
10552 wtoken = mOpeningApps.get(i-NC);
10553 mode = 2;
10554 }
10555 if (mLowerWallpaperTarget != null) {
10556 if (mLowerWallpaperTarget.mAppToken == wtoken
10557 || mUpperWallpaperTarget.mAppToken == wtoken) {
10558 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010559 }
10560 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010561 if (wtoken.appFullscreen) {
10562 WindowState ws = wtoken.findMainWindow();
10563 if (ws != null) {
10564 // If this is a compatibility mode
10565 // window, we will always use its anim.
10566 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
10567 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010568 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010569 bestAnimLayer = Integer.MAX_VALUE;
10570 } else if (ws.mLayer > bestAnimLayer) {
10571 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010572 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010573 bestAnimLayer = ws.mLayer;
10574 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010575 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010576 }
10577 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010578
Dianne Hackborn25994b42009-09-04 14:21:19 -070010579 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010580 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010581 "Wallpaper animation!");
10582 switch (transit) {
10583 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10584 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10585 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10586 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10587 break;
10588 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10589 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10590 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10591 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10592 break;
10593 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010594 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010595 "New transit: " + transit);
10596 } else if (oldWallpaper != null) {
10597 // We are transitioning from an activity with
10598 // a wallpaper to one without.
10599 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010600 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010601 "New transit away from wallpaper: " + transit);
10602 } else if (mWallpaperTarget != null) {
10603 // We are transitioning from an activity without
10604 // a wallpaper to now showing the wallpaper
10605 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010606 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010607 "New transit into wallpaper: " + transit);
10608 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010609
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010610 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
10611 mLastEnterAnimToken = animToken;
10612 mLastEnterAnimParams = animLp;
10613 } else if (mLastEnterAnimParams != null) {
10614 animLp = mLastEnterAnimParams;
10615 mLastEnterAnimToken = null;
10616 mLastEnterAnimParams = null;
10617 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010618
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010619 // If all closing windows are obscured, then there is
10620 // no need to do an animation. This is the case, for
10621 // example, when this transition is being done behind
10622 // the lock screen.
10623 if (!mPolicy.allowAppAnimationsLw()) {
10624 animLp = null;
10625 }
10626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010627 NN = mOpeningApps.size();
10628 for (i=0; i<NN; i++) {
10629 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010630 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010631 "Now opening app" + wtoken);
10632 wtoken.reportedVisible = false;
10633 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010634 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010635 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010637 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010638 wtoken.showAllWindowsLocked();
10639 }
10640 NN = mClosingApps.size();
10641 for (i=0; i<NN; i++) {
10642 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010643 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 "Now closing app" + wtoken);
10645 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010646 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010647 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010648 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010649 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010650 // Force the allDrawn flag, because we want to start
10651 // this guy's animations regardless of whether it's
10652 // gotten drawn.
10653 wtoken.allDrawn = true;
10654 }
10655
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010656 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010658 mOpeningApps.clear();
10659 mClosingApps.clear();
10660
10661 // This has changed the visibility of windows, so perform
10662 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010663 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010665 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10666 assignLayersLocked();
10667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010668 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010669 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010670 }
10671 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010672
Dianne Hackborn16064f92010-03-25 00:47:24 -070010673 int adjResult = 0;
10674
Dianne Hackborna8f60182009-09-01 19:01:50 -070010675 if (!animating && mAppTransitionRunning) {
10676 // We have finished the animation of an app transition. To do
10677 // this, we have delayed a lot of operations like showing and
10678 // hiding apps, moving apps in Z-order, etc. The app token list
10679 // reflects the correct Z-order, but the window list may now
10680 // be out of sync with it. So here we will just rebuild the
10681 // entire app window list. Fun!
10682 mAppTransitionRunning = false;
10683 // Clear information about apps that were moving.
10684 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010685
Dianne Hackborna8f60182009-09-01 19:01:50 -070010686 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010687 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010688 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010689 moveInputMethodWindowsIfNeededLocked(false);
10690 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010691 // Since the window list has been rebuilt, focus might
10692 // have to be recomputed since the actual order of windows
10693 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010694 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010695 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010696
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010697 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010698 // At this point, there was a window with a wallpaper that
10699 // was force hiding other windows behind it, but now it
10700 // is going away. This may be simple -- just animate
10701 // away the wallpaper and its window -- or it may be
10702 // hard -- the wallpaper now needs to be shown behind
10703 // something that was hidden.
10704 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010705 if (mLowerWallpaperTarget != null
10706 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010707 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010708 "wallpaperForceHiding changed with lower="
10709 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010710 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010711 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10712 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10713 if (mLowerWallpaperTarget.mAppToken.hidden) {
10714 // The lower target has become hidden before we
10715 // actually started the animation... let's completely
10716 // re-evaluate everything.
10717 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010718 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010719 }
10720 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010721 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010722 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010723 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010724 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010725 + " NEW: " + mWallpaperTarget
10726 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010727 if (mLowerWallpaperTarget == null) {
10728 // Whoops, we don't need a special wallpaper animation.
10729 // Clear them out.
10730 forceHiding = false;
10731 for (i=N-1; i>=0; i--) {
10732 WindowState w = (WindowState)mWindows.get(i);
10733 if (w.mSurface != null) {
10734 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010735 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010736 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010737 forceHiding = true;
10738 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10739 if (!w.mAnimating) {
10740 // We set the animation above so it
10741 // is not yet running.
10742 w.clearAnimation();
10743 }
10744 }
10745 }
10746 }
10747 }
10748 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010749
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010750 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010751 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010752 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010753 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010754 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010755
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010756 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010757 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010758 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010759 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010760 assignLayersLocked();
10761 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010762 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010763 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010764 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010765 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010766
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010767 if (mFocusMayChange) {
10768 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010769 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010770 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010771 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010772 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010773 }
10774
10775 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010776 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010777 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010778
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010779 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10780 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010781
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010782 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783
10784 // THIRD LOOP: Update the surfaces of all windows.
10785
10786 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10787
10788 boolean obscured = false;
10789 boolean blurring = false;
10790 boolean dimming = false;
10791 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010792 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010793 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010794
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010795 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797 for (i=N-1; i>=0; i--) {
10798 WindowState w = (WindowState)mWindows.get(i);
10799
10800 boolean displayed = false;
10801 final WindowManager.LayoutParams attrs = w.mAttrs;
10802 final int attrFlags = attrs.flags;
10803
10804 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010805 // XXX NOTE: The logic here could be improved. We have
10806 // the decision about whether to resize a window separated
10807 // from whether to hide the surface. This can cause us to
10808 // resize a surface even if we are going to hide it. You
10809 // can see this by (1) holding device in landscape mode on
10810 // home screen; (2) tapping browser icon (device will rotate
10811 // to landscape; (3) tap home. The wallpaper will be resized
10812 // in step 2 but then immediately hidden, causing us to
10813 // have to resize and then redraw it again in step 3. It
10814 // would be nice to figure out how to avoid this, but it is
10815 // difficult because we do need to resize surfaces in some
10816 // cases while they are hidden such as when first showing a
10817 // window.
10818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010819 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010821 TAG, "Placing surface #" + i + " " + w.mSurface
10822 + ": new=" + w.mShownFrame + ", old="
10823 + w.mLastShownFrame);
10824
10825 boolean resize;
10826 int width, height;
10827 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10828 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10829 w.mLastRequestedHeight != w.mRequestedHeight;
10830 // for a scaled surface, we just want to use
10831 // the requested size.
10832 width = w.mRequestedWidth;
10833 height = w.mRequestedHeight;
10834 w.mLastRequestedWidth = width;
10835 w.mLastRequestedHeight = height;
10836 w.mLastShownFrame.set(w.mShownFrame);
10837 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010838 if (SHOW_TRANSACTIONS) logSurface(w,
10839 "POS " + w.mShownFrame.left
10840 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010841 w.mSurfaceX = w.mShownFrame.left;
10842 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010843 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10844 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010845 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010846 if (!recoveringMemory) {
10847 reclaimSomeSurfaceMemoryLocked(w, "position");
10848 }
10849 }
10850 } else {
10851 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10852 width = w.mShownFrame.width();
10853 height = w.mShownFrame.height();
10854 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 }
10856
10857 if (resize) {
10858 if (width < 1) width = 1;
10859 if (height < 1) height = 1;
10860 if (w.mSurface != null) {
10861 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010862 if (SHOW_TRANSACTIONS) logSurface(w,
10863 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010864 + w.mShownFrame.top + " SIZE "
10865 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010866 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010867 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010868 w.mSurfaceW = width;
10869 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010870 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010871 w.mSurfaceX = w.mShownFrame.left;
10872 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 w.mSurface.setPosition(w.mShownFrame.left,
10874 w.mShownFrame.top);
10875 } catch (RuntimeException e) {
10876 // If something goes wrong with the surface (such
10877 // as running out of memory), don't take down the
10878 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010879 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 + "size=(" + width + "x" + height
10881 + "), pos=(" + w.mShownFrame.left
10882 + "," + w.mShownFrame.top + ")", e);
10883 if (!recoveringMemory) {
10884 reclaimSomeSurfaceMemoryLocked(w, "size");
10885 }
10886 }
10887 }
10888 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010889 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010890 w.mContentInsetsChanged =
10891 !w.mLastContentInsets.equals(w.mContentInsets);
10892 w.mVisibleInsetsChanged =
10893 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010894 boolean configChanged =
10895 w.mConfiguration != mCurConfiguration
10896 && (w.mConfiguration == null
10897 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010898 if (DEBUG_CONFIGURATION && configChanged) {
10899 Slog.v(TAG, "Win " + w + " config changed: "
10900 + mCurConfiguration);
10901 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010902 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010903 + ": configChanged=" + configChanged
10904 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010905 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010906 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010907 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010908 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010909 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 w.mLastFrame.set(w.mFrame);
10911 w.mLastContentInsets.set(w.mContentInsets);
10912 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010913 // If the screen is currently frozen, then keep
10914 // it frozen until this window draws at its new
10915 // orientation.
10916 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010917 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010918 "Resizing while display frozen: " + w);
10919 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010920 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010921 mWindowsFreezingScreen = true;
10922 // XXX should probably keep timeout from
10923 // when we first froze the display.
10924 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10925 mH.sendMessageDelayed(mH.obtainMessage(
10926 H.WINDOW_FREEZE_TIMEOUT), 2000);
10927 }
10928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010929 // If the orientation is changing, then we need to
10930 // hold off on unfreezing the display until this
10931 // window has been redrawn; to do that, we need
10932 // to go through the process of getting informed
10933 // by the application when it has finished drawing.
10934 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010935 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 "Orientation start waiting for draw in "
10937 + w + ", surface " + w.mSurface);
10938 w.mDrawPending = true;
10939 w.mCommitDrawPending = false;
10940 w.mReadyToShow = false;
10941 if (w.mAppToken != null) {
10942 w.mAppToken.allDrawn = false;
10943 }
10944 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010945 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 "Resizing window " + w + " to " + w.mFrame);
10947 mResizingWindows.add(w);
10948 } else if (w.mOrientationChanging) {
10949 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010950 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010951 "Orientation not waiting for draw in "
10952 + w + ", surface " + w.mSurface);
10953 w.mOrientationChanging = false;
10954 }
10955 }
10956 }
10957
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010958 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010959 if (!w.mLastHidden) {
10960 //dump();
Dianne Hackborn5943c202010-04-12 21:36:49 -070010961 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Window hiding: waitingToShow="
10962 + w.mRootToken.waitingToShow + " polvis="
10963 + w.mPolicyVisibility + " atthid="
10964 + w.mAttachedHidden + " tokhid="
10965 + w.mRootToken.hidden + " vis="
10966 + w.mViewVisibility);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010968 if (SHOW_TRANSACTIONS) logSurface(w,
10969 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010971 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 try {
10973 w.mSurface.hide();
10974 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010975 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 }
10977 }
Jeff Brown349703e2010-06-22 01:27:15 -070010978 if (ENABLE_NATIVE_INPUT_DISPATCH) {
10979 mInputMonitor.windowIsBecomingInvisibleLw(w);
10980 } else {
10981 mKeyWaiter.releasePendingPointerLocked(w.mSession);
10982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 }
10984 // If we are waiting for this window to handle an
10985 // orientation change, well, it is hidden, so
10986 // doesn't really matter. Note that this does
10987 // introduce a potential glitch if the window
10988 // becomes unhidden before it has drawn for the
10989 // new orientation.
10990 if (w.mOrientationChanging) {
10991 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010992 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 "Orientation change skips hidden " + w);
10994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 } else if (w.mLastLayer != w.mAnimLayer
10996 || w.mLastAlpha != w.mShownAlpha
10997 || w.mLastDsDx != w.mDsDx
10998 || w.mLastDtDx != w.mDtDx
10999 || w.mLastDsDy != w.mDsDy
11000 || w.mLastDtDy != w.mDtDy
11001 || w.mLastHScale != w.mHScale
11002 || w.mLastVScale != w.mVScale
11003 || w.mLastHidden) {
11004 displayed = true;
11005 w.mLastAlpha = w.mShownAlpha;
11006 w.mLastLayer = w.mAnimLayer;
11007 w.mLastDsDx = w.mDsDx;
11008 w.mLastDtDx = w.mDtDx;
11009 w.mLastDsDy = w.mDsDy;
11010 w.mLastDtDy = w.mDtDy;
11011 w.mLastHScale = w.mHScale;
11012 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011013 if (SHOW_TRANSACTIONS) logSurface(w,
11014 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011015 + " matrix=[" + (w.mDsDx*w.mHScale)
11016 + "," + (w.mDtDx*w.mVScale)
11017 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011018 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019 if (w.mSurface != null) {
11020 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011021 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011022 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011023 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 w.mSurface.setLayer(w.mAnimLayer);
11025 w.mSurface.setMatrix(
11026 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
11027 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
11028 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011029 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030 if (!recoveringMemory) {
11031 reclaimSomeSurfaceMemoryLocked(w, "update");
11032 }
11033 }
11034 }
11035
11036 if (w.mLastHidden && !w.mDrawPending
11037 && !w.mCommitDrawPending
11038 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011039 if (SHOW_TRANSACTIONS) logSurface(w,
11040 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011041 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011042 + " during relayout");
11043 if (showSurfaceRobustlyLocked(w)) {
11044 w.mHasDrawn = true;
11045 w.mLastHidden = false;
11046 } else {
11047 w.mOrientationChanging = false;
11048 }
11049 }
11050 if (w.mSurface != null) {
11051 w.mToken.hasVisible = true;
11052 }
11053 } else {
11054 displayed = true;
11055 }
11056
11057 if (displayed) {
11058 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080011059 if (attrs.width == LayoutParams.MATCH_PARENT
11060 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011061 covered = true;
11062 }
11063 }
11064 if (w.mOrientationChanging) {
11065 if (w.mDrawPending || w.mCommitDrawPending) {
11066 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011067 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011068 "Orientation continue waiting for draw in " + w);
11069 } else {
11070 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011071 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011072 "Orientation change complete in " + w);
11073 }
11074 }
11075 w.mToken.hasVisible = true;
11076 }
11077 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011078 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011079 "Orientation change skips hidden " + w);
11080 w.mOrientationChanging = false;
11081 }
11082
11083 final boolean canBeSeen = w.isDisplayedLw();
11084
11085 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
11086 focusDisplayed = true;
11087 }
11088
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011089 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011092 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093 if (w.mSurface != null) {
11094 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
11095 holdScreen = w.mSession;
11096 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070011097 if (!syswin && w.mAttrs.screenBrightness >= 0
11098 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 screenBrightness = w.mAttrs.screenBrightness;
11100 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050011101 if (!syswin && w.mAttrs.buttonBrightness >= 0
11102 && buttonBrightness < 0) {
11103 buttonBrightness = w.mAttrs.buttonBrightness;
11104 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050011105 if (canBeSeen
11106 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
11107 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
11108 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070011109 syswin = true;
11110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011111 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011112
Dianne Hackborn25994b42009-09-04 14:21:19 -070011113 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
11114 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 // This window completely covers everything behind it,
11116 // so we want to leave all of them as unblurred (for
11117 // performance reasons).
11118 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011119 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011120 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011121 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011122 obscured = true;
11123 if (mBackgroundFillerSurface == null) {
11124 try {
11125 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011126 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011127 0, dw, dh,
11128 PixelFormat.OPAQUE,
11129 Surface.FX_SURFACE_NORMAL);
11130 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011131 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011132 }
11133 }
11134 try {
11135 mBackgroundFillerSurface.setPosition(0, 0);
11136 mBackgroundFillerSurface.setSize(dw, dh);
11137 // Using the same layer as Dim because they will never be shown at the
11138 // same time.
11139 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
11140 mBackgroundFillerSurface.show();
11141 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011142 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011143 }
11144 backgroundFillerShown = true;
11145 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011146 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011147 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011148 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 + ": blurring=" + blurring
11150 + " obscured=" + obscured
11151 + " displayed=" + displayed);
11152 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
11153 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011154 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011156 if (mDimAnimator == null) {
11157 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011158 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011159 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011160 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011161 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011162 }
11163 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
11164 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011165 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011166 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011168 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 + mBlurSurface + ": CREATE");
11170 try {
Romain Guy06882f82009-06-10 13:36:04 -070011171 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011172 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011173 -1, 16, 16,
11174 PixelFormat.OPAQUE,
11175 Surface.FX_SURFACE_BLUR);
11176 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011177 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011178 }
11179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011180 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011181 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
11182 + mBlurSurface + ": pos=(0,0) (" +
11183 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011184 mBlurSurface.setPosition(0, 0);
11185 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011186 mBlurSurface.setLayer(w.mAnimLayer-2);
11187 if (!mBlurShown) {
11188 try {
11189 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
11190 + mBlurSurface + ": SHOW");
11191 mBlurSurface.show();
11192 } catch (RuntimeException e) {
11193 Slog.w(TAG, "Failure showing blur surface", e);
11194 }
11195 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011196 }
11197 }
11198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011199 }
11200 }
11201 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011202
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011203 if (obscuredChanged && mWallpaperTarget == w) {
11204 // This is the wallpaper target and its obscured state
11205 // changed... make sure the current wallaper's visibility
11206 // has been updated accordingly.
11207 updateWallpaperVisibilityLocked();
11208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011209 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011210
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011211 if (backgroundFillerShown == false && mBackgroundFillerShown) {
11212 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011213 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011214 try {
11215 mBackgroundFillerSurface.hide();
11216 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011217 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011218 }
11219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011220
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011221 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080011222 animating |= mDimAnimator.updateSurface(dimming, currentTime,
11223 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011224 }
Romain Guy06882f82009-06-10 13:36:04 -070011225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011227 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011228 + ": HIDE");
11229 try {
11230 mBlurSurface.hide();
11231 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011232 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011233 }
11234 mBlurShown = false;
11235 }
11236
Joe Onorato8a9b2202010-02-26 18:56:32 -080011237 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011238 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011239 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 }
11241
11242 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070011243
Joe Onorato8a9b2202010-02-26 18:56:32 -080011244 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011245 "With display frozen, orientationChangeComplete="
11246 + orientationChangeComplete);
11247 if (orientationChangeComplete) {
11248 if (mWindowsFreezingScreen) {
11249 mWindowsFreezingScreen = false;
11250 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
11251 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011252 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011253 }
Romain Guy06882f82009-06-10 13:36:04 -070011254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 i = mResizingWindows.size();
11256 if (i > 0) {
11257 do {
11258 i--;
11259 WindowState win = mResizingWindows.get(i);
11260 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011261 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
11262 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011263 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011264 boolean configChanged =
11265 win.mConfiguration != mCurConfiguration
11266 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011267 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
11268 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
11269 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011270 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011271 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011272 + " / " + mCurConfiguration + " / 0x"
11273 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011274 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011275 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011276 win.mClient.resized(win.mFrame.width(),
11277 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011278 win.mLastVisibleInsets, win.mDrawPending,
11279 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011280 win.mContentInsetsChanged = false;
11281 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011282 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011283 } catch (RemoteException e) {
11284 win.mOrientationChanging = false;
11285 }
11286 } while (i > 0);
11287 mResizingWindows.clear();
11288 }
Romain Guy06882f82009-06-10 13:36:04 -070011289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011290 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011291 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011292 i = mDestroySurface.size();
11293 if (i > 0) {
11294 do {
11295 i--;
11296 WindowState win = mDestroySurface.get(i);
11297 win.mDestroying = false;
11298 if (mInputMethodWindow == win) {
11299 mInputMethodWindow = null;
11300 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011301 if (win == mWallpaperTarget) {
11302 wallpaperDestroyed = true;
11303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011304 win.destroySurfaceLocked();
11305 } while (i > 0);
11306 mDestroySurface.clear();
11307 }
11308
11309 // Time to remove any exiting tokens?
11310 for (i=mExitingTokens.size()-1; i>=0; i--) {
11311 WindowToken token = mExitingTokens.get(i);
11312 if (!token.hasVisible) {
11313 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011314 if (token.windowType == TYPE_WALLPAPER) {
11315 mWallpaperTokens.remove(token);
11316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 }
11318 }
11319
11320 // Time to remove any exiting applications?
11321 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
11322 AppWindowToken token = mExitingAppTokens.get(i);
11323 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070011324 // Make sure there is no animation running on this token,
11325 // so any windows associated with it will be removed as
11326 // soon as their animations are complete
11327 token.animation = null;
11328 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 mAppTokens.remove(token);
11330 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011331 if (mLastEnterAnimToken == token) {
11332 mLastEnterAnimToken = null;
11333 mLastEnterAnimParams = null;
11334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011335 }
11336 }
11337
Dianne Hackborna8f60182009-09-01 19:01:50 -070011338 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011339
Dianne Hackborna8f60182009-09-01 19:01:50 -070011340 if (!animating && mAppTransitionRunning) {
11341 // We have finished the animation of an app transition. To do
11342 // this, we have delayed a lot of operations like showing and
11343 // hiding apps, moving apps in Z-order, etc. The app token list
11344 // reflects the correct Z-order, but the window list may now
11345 // be out of sync with it. So here we will just rebuild the
11346 // entire app window list. Fun!
11347 mAppTransitionRunning = false;
11348 needRelayout = true;
11349 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011350 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070011351 // Clear information about apps that were moving.
11352 mToBottomApps.clear();
11353 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011355 if (focusDisplayed) {
11356 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
11357 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011358 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011359 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011360 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011361 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011362 requestAnimationLocked(0);
11363 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011364 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
11365 }
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011366
11367 if (DEBUG_FREEZE) Slog.v(TAG, "Layout: mDisplayFrozen=" + mDisplayFrozen
11368 + " holdScreen=" + holdScreen);
11369 if (!mDisplayFrozen) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070011370 setHoldScreenLocked(holdScreen != null);
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011371 if (screenBrightness < 0 || screenBrightness > 1.0f) {
11372 mPowerManager.setScreenBrightnessOverride(-1);
11373 } else {
11374 mPowerManager.setScreenBrightnessOverride((int)
11375 (screenBrightness * Power.BRIGHTNESS_ON));
11376 }
11377 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
11378 mPowerManager.setButtonBrightnessOverride(-1);
11379 } else {
11380 mPowerManager.setButtonBrightnessOverride((int)
11381 (buttonBrightness * Power.BRIGHTNESS_ON));
11382 }
11383 if (holdScreen != mHoldingScreenOn) {
11384 mHoldingScreenOn = holdScreen;
11385 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
11386 mH.sendMessage(m);
11387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011388 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011389
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011390 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011391 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011392 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
11393 LocalPowerManager.BUTTON_EVENT, true);
11394 mTurnOnScreen = false;
11395 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011396
11397 // Check to see if we are now in a state where the screen should
11398 // be enabled, because the window obscured flags have changed.
11399 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011400 }
Jeff Brown46b9ac02010-04-22 18:58:52 -070011401
11402 /**
11403 * Must be called with the main window manager lock held.
11404 */
11405 void setHoldScreenLocked(boolean holding) {
11406 boolean state = mHoldingScreenWakeLock.isHeld();
11407 if (holding != state) {
11408 if (holding) {
11409 mHoldingScreenWakeLock.acquire();
11410 } else {
11411 mPolicy.screenOnStoppedLw();
11412 mHoldingScreenWakeLock.release();
11413 }
11414 }
11415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416
11417 void requestAnimationLocked(long delay) {
11418 if (!mAnimationPending) {
11419 mAnimationPending = true;
11420 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
11421 }
11422 }
Romain Guy06882f82009-06-10 13:36:04 -070011423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011424 /**
11425 * Have the surface flinger show a surface, robustly dealing with
11426 * error conditions. In particular, if there is not enough memory
11427 * to show the surface, then we will try to get rid of other surfaces
11428 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070011429 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011430 * @return Returns true if the surface was successfully shown.
11431 */
11432 boolean showSurfaceRobustlyLocked(WindowState win) {
11433 try {
11434 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011435 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011436 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011437 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011438 if (DEBUG_VISIBILITY) Slog.v(TAG,
11439 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011440 win.mTurnOnScreen = false;
11441 mTurnOnScreen = true;
11442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011443 }
11444 return true;
11445 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011446 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011447 }
Romain Guy06882f82009-06-10 13:36:04 -070011448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011449 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070011450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 return false;
11452 }
Romain Guy06882f82009-06-10 13:36:04 -070011453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011454 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
11455 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070011456
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011457 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011458 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070011459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011460 if (mForceRemoves == null) {
11461 mForceRemoves = new ArrayList<WindowState>();
11462 }
Romain Guy06882f82009-06-10 13:36:04 -070011463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011464 long callingIdentity = Binder.clearCallingIdentity();
11465 try {
11466 // There was some problem... first, do a sanity check of the
11467 // window list to make sure we haven't left any dangling surfaces
11468 // around.
11469 int N = mWindows.size();
11470 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011471 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011472 for (int i=0; i<N; i++) {
11473 WindowState ws = (WindowState)mWindows.get(i);
11474 if (ws.mSurface != null) {
11475 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011476 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 + ws + " surface=" + ws.mSurface
11478 + " token=" + win.mToken
11479 + " pid=" + ws.mSession.mPid
11480 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011481 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011482 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011483 ws.mSurface = null;
11484 mForceRemoves.add(ws);
11485 i--;
11486 N--;
11487 leakedSurface = true;
11488 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011489 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011490 + ws + " surface=" + ws.mSurface
11491 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011492 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011493 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011494 ws.mSurface = null;
11495 leakedSurface = true;
11496 }
11497 }
11498 }
Romain Guy06882f82009-06-10 13:36:04 -070011499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500 boolean killedApps = false;
11501 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011502 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011503 SparseIntArray pidCandidates = new SparseIntArray();
11504 for (int i=0; i<N; i++) {
11505 WindowState ws = (WindowState)mWindows.get(i);
11506 if (ws.mSurface != null) {
11507 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
11508 }
11509 }
11510 if (pidCandidates.size() > 0) {
11511 int[] pids = new int[pidCandidates.size()];
11512 for (int i=0; i<pids.length; i++) {
11513 pids[i] = pidCandidates.keyAt(i);
11514 }
11515 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070011516 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011517 killedApps = true;
11518 }
11519 } catch (RemoteException e) {
11520 }
11521 }
11522 }
Romain Guy06882f82009-06-10 13:36:04 -070011523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 if (leakedSurface || killedApps) {
11525 // We managed to reclaim some memory, so get rid of the trouble
11526 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011527 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011529 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011530 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 win.mSurface = null;
11532 }
Romain Guy06882f82009-06-10 13:36:04 -070011533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011534 try {
11535 win.mClient.dispatchGetNewSurface();
11536 } catch (RemoteException e) {
11537 }
11538 }
11539 } finally {
11540 Binder.restoreCallingIdentity(callingIdentity);
11541 }
11542 }
Romain Guy06882f82009-06-10 13:36:04 -070011543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011544 private boolean updateFocusedWindowLocked(int mode) {
11545 WindowState newFocus = computeFocusedWindowLocked();
11546 if (mCurrentFocus != newFocus) {
11547 // This check makes sure that we don't already have the focus
11548 // change message pending.
11549 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
11550 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011551 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011552 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
11553 final WindowState oldFocus = mCurrentFocus;
11554 mCurrentFocus = newFocus;
11555 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070011556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011557 final WindowState imWindow = mInputMethodWindow;
11558 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011559 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011561 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
11562 mLayoutNeeded = true;
11563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
11565 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011566 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
11567 // Client will do the layout, but we need to assign layers
11568 // for handleNewWindowLocked() below.
11569 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011570 }
11571 }
Jeff Brown349703e2010-06-22 01:27:15 -070011572
11573 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
11574 // If we defer assigning layers, then the caller is responsible for
11575 // doing this part.
11576 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 return true;
11579 }
11580 return false;
11581 }
Jeff Brown349703e2010-06-22 01:27:15 -070011582
11583 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
11584 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11585 mInputMonitor.setInputFocusLw(mCurrentFocus);
11586 } else {
11587 if (mCurrentFocus != null) {
11588 mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
11589 }
11590 }
11591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011592
11593 private WindowState computeFocusedWindowLocked() {
11594 WindowState result = null;
11595 WindowState win;
11596
11597 int i = mWindows.size() - 1;
11598 int nextAppIndex = mAppTokens.size()-1;
11599 WindowToken nextApp = nextAppIndex >= 0
11600 ? mAppTokens.get(nextAppIndex) : null;
11601
11602 while (i >= 0) {
11603 win = (WindowState)mWindows.get(i);
11604
Joe Onorato8a9b2202010-02-26 18:56:32 -080011605 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011606 TAG, "Looking for focus: " + i
11607 + " = " + win
11608 + ", flags=" + win.mAttrs.flags
11609 + ", canReceive=" + win.canReceiveKeys());
11610
11611 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011613 // If this window's application has been removed, just skip it.
11614 if (thisApp != null && thisApp.removed) {
11615 i--;
11616 continue;
11617 }
Romain Guy06882f82009-06-10 13:36:04 -070011618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011619 // If there is a focused app, don't allow focus to go to any
11620 // windows below it. If this is an application window, step
11621 // through the app tokens until we find its app.
11622 if (thisApp != null && nextApp != null && thisApp != nextApp
11623 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11624 int origAppIndex = nextAppIndex;
11625 while (nextAppIndex > 0) {
11626 if (nextApp == mFocusedApp) {
11627 // Whoops, we are below the focused app... no focus
11628 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011629 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011630 TAG, "Reached focused app: " + mFocusedApp);
11631 return null;
11632 }
11633 nextAppIndex--;
11634 nextApp = mAppTokens.get(nextAppIndex);
11635 if (nextApp == thisApp) {
11636 break;
11637 }
11638 }
11639 if (thisApp != nextApp) {
11640 // Uh oh, the app token doesn't exist! This shouldn't
11641 // happen, but if it does we can get totally hosed...
11642 // so restart at the original app.
11643 nextAppIndex = origAppIndex;
11644 nextApp = mAppTokens.get(nextAppIndex);
11645 }
11646 }
11647
11648 // Dispatch to this window if it is wants key events.
11649 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011650 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651 TAG, "Found focus @ " + i + " = " + win);
11652 result = win;
11653 break;
11654 }
11655
11656 i--;
11657 }
11658
11659 return result;
11660 }
11661
11662 private void startFreezingDisplayLocked() {
11663 if (mDisplayFrozen) {
Chris Tate2ad63a92009-03-25 17:36:48 -070011664 // Freezing the display also suspends key event delivery, to
11665 // keep events from going astray while the display is reconfigured.
11666 // If someone has changed orientation again while the screen is
11667 // still frozen, the events will continue to be blocked while the
11668 // successive orientation change is processed. To prevent spurious
11669 // ANRs, we reset the event dispatch timeout in this case.
Jeff Brown349703e2010-06-22 01:27:15 -070011670 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
11671 synchronized (mKeyWaiter) {
11672 mKeyWaiter.mWasFrozen = true;
11673 }
Chris Tate2ad63a92009-03-25 17:36:48 -070011674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 return;
11676 }
Romain Guy06882f82009-06-10 13:36:04 -070011677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011678 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011680 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011681 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 if (mFreezeGcPending != 0) {
11683 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011684 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011685 mH.removeMessages(H.FORCE_GC);
11686 Runtime.getRuntime().gc();
11687 mFreezeGcPending = now;
11688 }
11689 } else {
11690 mFreezeGcPending = now;
11691 }
Romain Guy06882f82009-06-10 13:36:04 -070011692
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011693 if (DEBUG_FREEZE) Slog.v(TAG, "*** FREEZING DISPLAY", new RuntimeException());
11694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070011696
11697 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11698 mInputMonitor.freezeInputDispatchingLw();
11699 }
11700
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011701 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11702 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011703 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011704 mAppTransitionReady = true;
11705 }
Romain Guy06882f82009-06-10 13:36:04 -070011706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011707 if (PROFILE_ORIENTATION) {
11708 File file = new File("/data/system/frozen");
11709 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11710 }
11711 Surface.freezeDisplay(0);
11712 }
Romain Guy06882f82009-06-10 13:36:04 -070011713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011714 private void stopFreezingDisplayLocked() {
11715 if (!mDisplayFrozen) {
11716 return;
11717 }
Romain Guy06882f82009-06-10 13:36:04 -070011718
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011719 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11720 return;
11721 }
11722
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011723 if (DEBUG_FREEZE) Slog.v(TAG, "*** UNFREEZING DISPLAY", new RuntimeException());
11724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 mDisplayFrozen = false;
11726 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11727 if (PROFILE_ORIENTATION) {
11728 Debug.stopMethodTracing();
11729 }
11730 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070011731
Chris Tate2ad63a92009-03-25 17:36:48 -070011732 // Reset the key delivery timeout on unfreeze, too. We force a wakeup here
11733 // too because regular key delivery processing should resume immediately.
Jeff Brown349703e2010-06-22 01:27:15 -070011734 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11735 mInputMonitor.thawInputDispatchingLw();
11736 } else {
11737 synchronized (mKeyWaiter) {
11738 mKeyWaiter.mWasFrozen = true;
11739 mKeyWaiter.notifyAll();
11740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011741 }
11742
Christopher Tateb696aee2010-04-02 19:08:30 -070011743 // While the display is frozen we don't re-compute the orientation
11744 // to avoid inconsistent states. However, something interesting
11745 // could have actually changed during that time so re-evaluate it
11746 // now to catch that.
11747 if (updateOrientationFromAppTokensLocked()) {
11748 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11749 }
11750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 // A little kludge: a lot could have happened while the
11752 // display was frozen, so now that we are coming back we
11753 // do a gc so that any remote references the system
11754 // processes holds on others can be released if they are
11755 // no longer needed.
11756 mH.removeMessages(H.FORCE_GC);
11757 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11758 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 mScreenFrozenLock.release();
11761 }
Romain Guy06882f82009-06-10 13:36:04 -070011762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011763 @Override
11764 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11765 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11766 != PackageManager.PERMISSION_GRANTED) {
11767 pw.println("Permission Denial: can't dump WindowManager from from pid="
11768 + Binder.getCallingPid()
11769 + ", uid=" + Binder.getCallingUid());
11770 return;
11771 }
Romain Guy06882f82009-06-10 13:36:04 -070011772
Jeff Brown46b9ac02010-04-22 18:58:52 -070011773 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11774 pw.println("Input Dispatcher State:");
11775 mInputManager.dump(pw);
11776 } else {
11777 pw.println("Input State:");
11778 mQueue.dump(pw, " ");
11779 }
Dianne Hackborna2e92262010-03-02 17:19:29 -080011780 pw.println(" ");
11781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011782 synchronized(mWindowMap) {
11783 pw.println("Current Window Manager state:");
11784 for (int i=mWindows.size()-1; i>=0; i--) {
11785 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011786 pw.print(" Window #"); pw.print(i); pw.print(' ');
11787 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011788 w.dump(pw, " ");
11789 }
11790 if (mInputMethodDialogs.size() > 0) {
11791 pw.println(" ");
11792 pw.println(" Input method dialogs:");
11793 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11794 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011795 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796 }
11797 }
11798 if (mPendingRemove.size() > 0) {
11799 pw.println(" ");
11800 pw.println(" Remove pending for:");
11801 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11802 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011803 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11804 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 w.dump(pw, " ");
11806 }
11807 }
11808 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11809 pw.println(" ");
11810 pw.println(" Windows force removing:");
11811 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11812 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011813 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11814 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011815 w.dump(pw, " ");
11816 }
11817 }
11818 if (mDestroySurface.size() > 0) {
11819 pw.println(" ");
11820 pw.println(" Windows waiting to destroy their surface:");
11821 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11822 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011823 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11824 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011825 w.dump(pw, " ");
11826 }
11827 }
11828 if (mLosingFocus.size() > 0) {
11829 pw.println(" ");
11830 pw.println(" Windows losing focus:");
11831 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11832 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011833 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11834 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011835 w.dump(pw, " ");
11836 }
11837 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011838 if (mResizingWindows.size() > 0) {
11839 pw.println(" ");
11840 pw.println(" Windows waiting to resize:");
11841 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11842 WindowState w = mResizingWindows.get(i);
11843 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11844 pw.print(w); pw.println(":");
11845 w.dump(pw, " ");
11846 }
11847 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011848 if (mSessions.size() > 0) {
11849 pw.println(" ");
11850 pw.println(" All active sessions:");
11851 Iterator<Session> it = mSessions.iterator();
11852 while (it.hasNext()) {
11853 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011854 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011855 s.dump(pw, " ");
11856 }
11857 }
11858 if (mTokenMap.size() > 0) {
11859 pw.println(" ");
11860 pw.println(" All tokens:");
11861 Iterator<WindowToken> it = mTokenMap.values().iterator();
11862 while (it.hasNext()) {
11863 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011864 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011865 token.dump(pw, " ");
11866 }
11867 }
11868 if (mTokenList.size() > 0) {
11869 pw.println(" ");
11870 pw.println(" Window token list:");
11871 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011872 pw.print(" #"); pw.print(i); pw.print(": ");
11873 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011874 }
11875 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011876 if (mWallpaperTokens.size() > 0) {
11877 pw.println(" ");
11878 pw.println(" Wallpaper tokens:");
11879 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11880 WindowToken token = mWallpaperTokens.get(i);
11881 pw.print(" Wallpaper #"); pw.print(i);
11882 pw.print(' '); pw.print(token); pw.println(':');
11883 token.dump(pw, " ");
11884 }
11885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 if (mAppTokens.size() > 0) {
11887 pw.println(" ");
11888 pw.println(" Application tokens in Z order:");
11889 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011890 pw.print(" App #"); pw.print(i); pw.print(": ");
11891 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011892 }
11893 }
11894 if (mFinishedStarting.size() > 0) {
11895 pw.println(" ");
11896 pw.println(" Finishing start of application tokens:");
11897 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11898 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011899 pw.print(" Finished Starting #"); pw.print(i);
11900 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011901 token.dump(pw, " ");
11902 }
11903 }
11904 if (mExitingTokens.size() > 0) {
11905 pw.println(" ");
11906 pw.println(" Exiting tokens:");
11907 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11908 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011909 pw.print(" Exiting #"); pw.print(i);
11910 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 token.dump(pw, " ");
11912 }
11913 }
11914 if (mExitingAppTokens.size() > 0) {
11915 pw.println(" ");
11916 pw.println(" Exiting application tokens:");
11917 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11918 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011919 pw.print(" Exiting App #"); pw.print(i);
11920 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 token.dump(pw, " ");
11922 }
11923 }
11924 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011925 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11926 pw.print(" mLastFocus="); pw.println(mLastFocus);
11927 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11928 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11929 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011930 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011931 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11932 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11933 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11934 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011935 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11936 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11937 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011938 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11939 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11940 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11941 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011942 if (mDimAnimator != null) {
11943 mDimAnimator.printTo(pw);
11944 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011945 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011946 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011947 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011948 pw.print(mInputMethodAnimLayerAdjustment);
11949 pw.print(" mWallpaperAnimLayerAdjustment=");
11950 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011951 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11952 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011953 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11954 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011955 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11956 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011957 pw.print(" mRotation="); pw.print(mRotation);
11958 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11959 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11960 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11961 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11962 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11963 pw.print(" mNextAppTransition=0x");
11964 pw.print(Integer.toHexString(mNextAppTransition));
11965 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011966 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011967 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011968 if (mNextAppTransitionPackage != null) {
11969 pw.print(" mNextAppTransitionPackage=");
11970 pw.print(mNextAppTransitionPackage);
11971 pw.print(", mNextAppTransitionEnter=0x");
11972 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11973 pw.print(", mNextAppTransitionExit=0x");
11974 pw.print(Integer.toHexString(mNextAppTransitionExit));
11975 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011976 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11977 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011978 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11979 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11980 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11981 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011982 if (mOpeningApps.size() > 0) {
11983 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11984 }
11985 if (mClosingApps.size() > 0) {
11986 pw.print(" mClosingApps="); pw.println(mClosingApps);
11987 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011988 if (mToTopApps.size() > 0) {
11989 pw.print(" mToTopApps="); pw.println(mToTopApps);
11990 }
11991 if (mToBottomApps.size() > 0) {
11992 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11993 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011994 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11995 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
Jeff Brown349703e2010-06-22 01:27:15 -070011996
11997 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
11998 pw.println(" KeyWaiter state:");
11999 pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin);
12000 pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
12001 pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished);
12002 pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
12003 pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
12004 pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
12005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012006 }
12007 }
12008
Jeff Brown349703e2010-06-22 01:27:15 -070012009 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 public void monitor() {
12011 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050012012 synchronized (mKeyguardTokenWatcher) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 synchronized (mKeyWaiter) { }
Jeff Brown349703e2010-06-22 01:27:15 -070012014 synchronized (mInputMonitor) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012016
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070012017 public void virtualKeyFeedback(KeyEvent event) {
12018 mPolicy.keyFeedbackFromInput(event);
12019 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012020
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012021 /**
12022 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012023 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012024 */
12025 private static class DimAnimator {
12026 Surface mDimSurface;
12027 boolean mDimShown = false;
12028 float mDimCurrentAlpha;
12029 float mDimTargetAlpha;
12030 float mDimDeltaPerMs;
12031 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012032
12033 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012034
12035 DimAnimator (SurfaceSession session) {
12036 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012037 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012038 + mDimSurface + ": CREATE");
12039 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080012040 mDimSurface = new Surface(session, 0,
12041 "DimSurface",
12042 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012043 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010012044 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012045 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012046 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012047 }
12048 }
12049 }
12050
12051 /**
12052 * Show the dim surface.
12053 */
12054 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070012055 if (!mDimShown) {
12056 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
12057 dw + "x" + dh + ")");
12058 mDimShown = true;
12059 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012060 mLastDimWidth = dw;
12061 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070012062 mDimSurface.setPosition(0, 0);
12063 mDimSurface.setSize(dw, dh);
12064 mDimSurface.show();
12065 } catch (RuntimeException e) {
12066 Slog.w(TAG, "Failure showing dim surface", e);
12067 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012068 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
12069 mLastDimWidth = dw;
12070 mLastDimHeight = dh;
12071 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012072 }
12073 }
12074
12075 /**
12076 * Set's the dim surface's layer and update dim parameters that will be used in
12077 * {@link updateSurface} after all windows are examined.
12078 */
12079 void updateParameters(WindowState w, long currentTime) {
12080 mDimSurface.setLayer(w.mAnimLayer-1);
12081
12082 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012083 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070012084 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012085 if (mDimTargetAlpha != target) {
12086 // If the desired dim level has changed, then
12087 // start an animation to it.
12088 mLastDimAnimTime = currentTime;
12089 long duration = (w.mAnimating && w.mAnimation != null)
12090 ? w.mAnimation.computeDurationHint()
12091 : DEFAULT_DIM_DURATION;
12092 if (target > mDimTargetAlpha) {
12093 // This is happening behind the activity UI,
12094 // so we can make it run a little longer to
12095 // give a stronger impression without disrupting
12096 // the user.
12097 duration *= DIM_DURATION_MULTIPLIER;
12098 }
12099 if (duration < 1) {
12100 // Don't divide by zero
12101 duration = 1;
12102 }
12103 mDimTargetAlpha = target;
12104 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
12105 }
12106 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012107
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012108 /**
12109 * Updating the surface's alpha. Returns true if the animation continues, or returns
12110 * false when the animation is finished and the dim surface is hidden.
12111 */
12112 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
12113 if (!dimming) {
12114 if (mDimTargetAlpha != 0) {
12115 mLastDimAnimTime = currentTime;
12116 mDimTargetAlpha = 0;
12117 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
12118 }
12119 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012120
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012121 boolean animating = false;
12122 if (mLastDimAnimTime != 0) {
12123 mDimCurrentAlpha += mDimDeltaPerMs
12124 * (currentTime-mLastDimAnimTime);
12125 boolean more = true;
12126 if (displayFrozen) {
12127 // If the display is frozen, there is no reason to animate.
12128 more = false;
12129 } else if (mDimDeltaPerMs > 0) {
12130 if (mDimCurrentAlpha > mDimTargetAlpha) {
12131 more = false;
12132 }
12133 } else if (mDimDeltaPerMs < 0) {
12134 if (mDimCurrentAlpha < mDimTargetAlpha) {
12135 more = false;
12136 }
12137 } else {
12138 more = false;
12139 }
12140
12141 // Do we need to continue animating?
12142 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012143 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012144 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
12145 mLastDimAnimTime = currentTime;
12146 mDimSurface.setAlpha(mDimCurrentAlpha);
12147 animating = true;
12148 } else {
12149 mDimCurrentAlpha = mDimTargetAlpha;
12150 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012151 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012152 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
12153 mDimSurface.setAlpha(mDimCurrentAlpha);
12154 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012155 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012156 + ": HIDE");
12157 try {
12158 mDimSurface.hide();
12159 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012160 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012161 }
12162 mDimShown = false;
12163 }
12164 }
12165 }
12166 return animating;
12167 }
12168
12169 public void printTo(PrintWriter pw) {
12170 pw.print(" mDimShown="); pw.print(mDimShown);
12171 pw.print(" current="); pw.print(mDimCurrentAlpha);
12172 pw.print(" target="); pw.print(mDimTargetAlpha);
12173 pw.print(" delta="); pw.print(mDimDeltaPerMs);
12174 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
12175 }
12176 }
12177
12178 /**
12179 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
12180 * This is used for opening/closing transition for apps in compatible mode.
12181 */
12182 private static class FadeInOutAnimation extends Animation {
12183 int mWidth;
12184 boolean mFadeIn;
12185
12186 public FadeInOutAnimation(boolean fadeIn) {
12187 setInterpolator(new AccelerateInterpolator());
12188 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
12189 mFadeIn = fadeIn;
12190 }
12191
12192 @Override
12193 protected void applyTransformation(float interpolatedTime, Transformation t) {
12194 float x = interpolatedTime;
12195 if (!mFadeIn) {
12196 x = 1.0f - x; // reverse the interpolation for fade out
12197 }
12198 if (x < 0.5) {
12199 // move the window out of the screen.
12200 t.getMatrix().setTranslate(mWidth, 0);
12201 } else {
12202 t.getMatrix().setTranslate(0, 0);// show
12203 t.setAlpha((x - 0.5f) * 2);
12204 }
12205 }
12206
12207 @Override
12208 public void initialize(int width, int height, int parentWidth, int parentHeight) {
12209 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
12210 mWidth = width;
12211 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012212
12213 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070012214 public int getZAdjustment() {
12215 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012216 }
12217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218}