blob: 503dbb9e81258b277c8f1b1f92f04b4db886f5e7 [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 Brown46b9ac0a2010-04-22 18:58:52 -0700104import android.view.InputChannel;
105import android.view.InputQueue;
106import android.view.InputTarget;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.view.KeyEvent;
108import android.view.MotionEvent;
109import android.view.RawInputEvent;
110import android.view.Surface;
111import android.view.SurfaceSession;
112import android.view.View;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700113import android.view.ViewConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.ViewTreeObserver;
115import android.view.WindowManager;
116import android.view.WindowManagerImpl;
117import android.view.WindowManagerPolicy;
118import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700119import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import android.view.animation.Animation;
121import android.view.animation.AnimationUtils;
122import android.view.animation.Transformation;
123
124import java.io.BufferedWriter;
125import java.io.File;
126import java.io.FileDescriptor;
127import java.io.IOException;
128import java.io.OutputStream;
129import java.io.OutputStreamWriter;
130import java.io.PrintWriter;
131import java.io.StringWriter;
132import java.net.Socket;
133import java.util.ArrayList;
134import java.util.HashMap;
135import java.util.HashSet;
136import java.util.Iterator;
137import java.util.List;
138
139/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700140public class WindowManagerService extends IWindowManager.Stub
141 implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 static final String TAG = "WindowManager";
143 static final boolean DEBUG = false;
144 static final boolean DEBUG_FOCUS = false;
145 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800146 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800147 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 static final boolean DEBUG_LAYERS = false;
149 static final boolean DEBUG_INPUT = false;
150 static final boolean DEBUG_INPUT_METHOD = false;
151 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700152 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700154 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_APP_TRANSITIONS = false;
156 static final boolean DEBUG_STARTING_WINDOW = false;
157 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700158 static final boolean DEBUG_WALLPAPER = 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 Brown46b9ac0a2010-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;
Romain Guy06882f82009-06-10 13:36:04 -0700205
Dianne Hackborncfaef692009-06-15 14:24:44 -0700206 static final int INJECT_FAILED = 0;
207 static final int INJECT_SUCCEEDED = 1;
208 static final int INJECT_NO_PERMISSION = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 static final int UPDATE_FOCUS_NORMAL = 0;
211 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
212 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
213 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700214
Michael Chane96440f2009-05-06 10:27:36 -0700215 /** The minimum time between dispatching touch events. */
216 int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
217
218 // Last touch event time
219 long mLastTouchEventTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700220
Michael Chane96440f2009-05-06 10:27:36 -0700221 // Last touch event type
222 int mLastTouchEventType = OTHER_EVENT;
Romain Guy06882f82009-06-10 13:36:04 -0700223
Michael Chane96440f2009-05-06 10:27:36 -0700224 // Time to wait before calling useractivity again. This saves CPU usage
225 // when we get a flood of touch events.
226 static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
227
228 // Last time we call user activity
229 long mLastUserActivityCallTime = 0;
230
Romain Guy06882f82009-06-10 13:36:04 -0700231 // Last time we updated battery stats
Michael Chane96440f2009-05-06 10:27:36 -0700232 long mLastBatteryStatsCallTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700235 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236
237 /**
238 * Condition waited on by {@link #reenableKeyguard} to know the call to
239 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500240 * This is set to true only if mKeyguardTokenWatcher.acquired() has
241 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500243 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244
Jim Miller284b62e2010-06-08 14:27:42 -0700245 private static final int ALLOW_DISABLE_YES = 1;
246 private static final int ALLOW_DISABLE_NO = 0;
247 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
248 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
249
Mike Lockwood983ee092009-11-22 01:42:24 -0500250 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
251 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700253 if (shouldAllowDisableKeyguard()) {
254 mPolicy.enableKeyguard(false);
255 mKeyguardDisabled = true;
256 } else {
257 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 }
260 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700261 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500262 synchronized (mKeyguardTokenWatcher) {
263 mKeyguardDisabled = false;
264 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
266 }
267 };
268
Jim Miller284b62e2010-06-08 14:27:42 -0700269 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
270 @Override
271 public void onReceive(Context context, Intent intent) {
272 mPolicy.enableKeyguard(true);
273 synchronized(mKeyguardTokenWatcher) {
274 // lazily evaluate this next time we're asked to disable keyguard
275 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
276 mKeyguardDisabled = false;
277 }
278 }
279 };
280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 final Context mContext;
282
283 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
288
289 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 /**
294 * All currently active sessions with clients.
295 */
296 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 /**
299 * Mapping from an IWindow IBinder to the server's Window object.
300 * This is also used as the lock for all of our state.
301 */
302 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
303
304 /**
305 * Mapping from a token IBinder to a WindowToken object.
306 */
307 final HashMap<IBinder, WindowToken> mTokenMap =
308 new HashMap<IBinder, WindowToken>();
309
310 /**
311 * The same tokens as mTokenMap, stored in a list for efficient iteration
312 * over them.
313 */
314 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 /**
317 * Window tokens that are in the process of exiting, but still
318 * on screen for animations.
319 */
320 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
321
322 /**
323 * Z-ordered (bottom-most first) list of all application tokens, for
324 * controlling the ordering of windows in different applications. This
325 * contains WindowToken objects.
326 */
327 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
328
329 /**
330 * Application tokens that are in the process of exiting, but still
331 * on screen for animations.
332 */
333 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
334
335 /**
336 * List of window tokens that have finished starting their application,
337 * and now need to have the policy remove their windows.
338 */
339 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
340
341 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700342 * This was the app token that was used to retrieve the last enter
343 * animation. It will be used for the next exit animation.
344 */
345 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800346
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700347 /**
348 * These were the layout params used to retrieve the last enter animation.
349 * They will be used for the next exit animation.
350 */
351 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800352
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700353 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 * Z-ordered (bottom-most first) list of all Window objects.
355 */
356 final ArrayList mWindows = new ArrayList();
357
358 /**
359 * Windows that are being resized. Used so we can tell the client about
360 * the resize after closing the transaction in which we resized the
361 * underlying surface.
362 */
363 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
364
365 /**
366 * Windows whose animations have ended and now must be removed.
367 */
368 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
369
370 /**
371 * Windows whose surface should be destroyed.
372 */
373 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
374
375 /**
376 * Windows that have lost input focus and are waiting for the new
377 * focus window to be displayed before they are told about this.
378 */
379 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
380
381 /**
382 * This is set when we have run out of memory, and will either be an empty
383 * list or contain windows that need to be force removed.
384 */
385 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700390 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 Surface mBlurSurface;
392 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 final float[] mTmpFloats = new float[9];
397
398 boolean mSafeMode;
399 boolean mDisplayEnabled = false;
400 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700401 int mInitialDisplayWidth = 0;
402 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 int mRotation = 0;
404 int mRequestedRotation = 0;
405 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700406 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 ArrayList<IRotationWatcher> mRotationWatchers
408 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 boolean mLayoutNeeded = true;
411 boolean mAnimationPending = false;
412 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800413 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 boolean mWindowsFreezingScreen = false;
415 long mFreezeGcPending = 0;
416 int mAppsFreezingScreen = 0;
417
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800418 int mLayoutSeq = 0;
419
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800420 // State while inside of layoutAndPlaceSurfacesLocked().
421 boolean mFocusMayChange;
422
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800423 Configuration mCurConfiguration = new Configuration();
424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 // This is held as long as we have the screen frozen, to give us time to
426 // perform a rotation animation when turning off shows the lock screen which
427 // changes the orientation.
428 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 // State management of app transitions. When we are preparing for a
431 // transition, mNextAppTransition will be the kind of transition to
432 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
433 // mOpeningApps and mClosingApps are the lists of tokens that will be
434 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700435 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700436 String mNextAppTransitionPackage;
437 int mNextAppTransitionEnter;
438 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700440 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 boolean mAppTransitionTimeout = false;
442 boolean mStartingIconInTransition = false;
443 boolean mSkipAppTransitionAnimation = false;
444 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
445 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700446 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
447 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 //flag to detect fat touch events
450 boolean mFatTouch = false;
451 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 H mH = new H();
454
455 WindowState mCurrentFocus = null;
456 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 // This just indicates the window the input method is on top of, not
459 // necessarily the window its input is going to.
460 WindowState mInputMethodTarget = null;
461 WindowState mUpcomingInputMethodTarget = null;
462 boolean mInputMethodTargetWaitingAnim;
463 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 WindowState mInputMethodWindow = null;
466 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
467
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700468 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800469
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700470 // If non-null, this is the currently visible window that is associated
471 // with the wallpaper.
472 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700473 // If non-null, we are in the middle of animating from one wallpaper target
474 // to another, and this is the lower one in Z-order.
475 WindowState mLowerWallpaperTarget = null;
476 // If non-null, we are in the middle of animating from one wallpaper target
477 // to another, and this is the higher one in Z-order.
478 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700479 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700480 float mLastWallpaperX = -1;
481 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800482 float mLastWallpaperXStep = -1;
483 float mLastWallpaperYStep = -1;
Dianne Hackborn6adba242009-11-10 11:10:09 -0800484 boolean mSendingPointersToWallpaper = false;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700485 // This is set when we are waiting for a wallpaper to tell us it is done
486 // changing its scroll position.
487 WindowState mWaitingOnWallpaper;
488 // The last time we had a timeout when waiting for a wallpaper.
489 long mLastWallpaperTimeoutTime;
490 // We give a wallpaper up to 150ms to finish scrolling.
491 static final long WALLPAPER_TIMEOUT = 150;
492 // Time we wait after a timeout before trying to wait again.
493 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 AppWindowToken mFocusedApp = null;
496
497 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 float mWindowAnimationScale = 1.0f;
500 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 final KeyWaiter mKeyWaiter = new KeyWaiter();
503 final KeyQ mQueue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700504 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 final InputDispatcherThread mInputThread;
506
507 // Who is holding the screen on.
508 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700509 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700510
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700511 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 /**
514 * Whether the UI is currently running in touch mode (not showing
515 * navigational focus because the user is directly pressing the screen).
516 */
517 boolean mInTouchMode = false;
518
519 private ViewServer mViewServer;
520
521 final Rect mTempRect = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -0700522
Dianne Hackbornc485a602009-03-24 22:39:49 -0700523 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700524 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700525
526 // The frame use to limit the size of the app running in compatibility mode.
527 Rect mCompatibleScreenFrame = new Rect();
528 // The surface used to fill the outer rim of the app running in compatibility mode.
529 Surface mBackgroundFillerSurface = null;
530 boolean mBackgroundFillerShown = false;
531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 public static WindowManagerService main(Context context,
533 PowerManagerService pm, boolean haveInputMethods) {
534 WMThread thr = new WMThread(context, pm, haveInputMethods);
535 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 synchronized (thr) {
538 while (thr.mService == null) {
539 try {
540 thr.wait();
541 } catch (InterruptedException e) {
542 }
543 }
544 }
Romain Guy06882f82009-06-10 13:36:04 -0700545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 return thr.mService;
547 }
Romain Guy06882f82009-06-10 13:36:04 -0700548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 static class WMThread extends Thread {
550 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 private final Context mContext;
553 private final PowerManagerService mPM;
554 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 public WMThread(Context context, PowerManagerService pm,
557 boolean haveInputMethods) {
558 super("WindowManager");
559 mContext = context;
560 mPM = pm;
561 mHaveInputMethods = haveInputMethods;
562 }
Romain Guy06882f82009-06-10 13:36:04 -0700563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 public void run() {
565 Looper.prepare();
566 WindowManagerService s = new WindowManagerService(mContext, mPM,
567 mHaveInputMethods);
568 android.os.Process.setThreadPriority(
569 android.os.Process.THREAD_PRIORITY_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -0700570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 synchronized (this) {
572 mService = s;
573 notifyAll();
574 }
Romain Guy06882f82009-06-10 13:36:04 -0700575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 Looper.loop();
577 }
578 }
579
580 static class PolicyThread extends Thread {
581 private final WindowManagerPolicy mPolicy;
582 private final WindowManagerService mService;
583 private final Context mContext;
584 private final PowerManagerService mPM;
585 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 public PolicyThread(WindowManagerPolicy policy,
588 WindowManagerService service, Context context,
589 PowerManagerService pm) {
590 super("WindowManagerPolicy");
591 mPolicy = policy;
592 mService = service;
593 mContext = context;
594 mPM = pm;
595 }
Romain Guy06882f82009-06-10 13:36:04 -0700596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 public void run() {
598 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800599 WindowManagerPolicyThread.set(this, Looper.myLooper());
600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800602 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 android.os.Process.setThreadPriority(
604 android.os.Process.THREAD_PRIORITY_FOREGROUND);
605 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 synchronized (this) {
608 mRunning = true;
609 notifyAll();
610 }
Romain Guy06882f82009-06-10 13:36:04 -0700611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 Looper.loop();
613 }
614 }
615
616 private WindowManagerService(Context context, PowerManagerService pm,
617 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700618 if (MEASURE_LATENCY) {
619 lt = new LatencyTimer(100, 1000);
620 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 mContext = context;
623 mHaveInputMethods = haveInputMethods;
624 mLimitedAlphaCompositing = context.getResources().getBoolean(
625 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 mPowerManager = pm;
628 mPowerManager.setPolicy(mPolicy);
629 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
630 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
631 "SCREEN_FROZEN");
632 mScreenFrozenLock.setReferenceCounted(false);
633
634 mActivityManager = ActivityManagerNative.getDefault();
635 mBatteryStats = BatteryStatsService.getService();
636
637 // Get persisted window scale setting
638 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
639 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
640 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
641 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700642
Jim Miller284b62e2010-06-08 14:27:42 -0700643 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
644 IntentFilter filter = new IntentFilter();
645 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
646 mContext.registerReceiver(mBroadcastReceiver, filter);
647
Michael Chan9f028e62009-08-04 17:37:46 -0700648 int max_events_per_sec = 35;
649 try {
650 max_events_per_sec = Integer.parseInt(SystemProperties
651 .get("windowsmgr.max_events_per_sec"));
652 if (max_events_per_sec < 1) {
653 max_events_per_sec = 35;
654 }
655 } catch (NumberFormatException e) {
656 }
657 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
658
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700659 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
660 "KEEP_SCREEN_ON_FLAG");
661 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700663 if (ENABLE_NATIVE_INPUT_DISPATCH) {
664 mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager);
665 } else {
666 mInputManager = null;
667 }
668 mQueue = new KeyQ();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 mInputThread = new InputDispatcherThread();
Romain Guy06882f82009-06-10 13:36:04 -0700670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
672 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 synchronized (thr) {
675 while (!thr.mRunning) {
676 try {
677 thr.wait();
678 } catch (InterruptedException e) {
679 }
680 }
681 }
Romain Guy06882f82009-06-10 13:36:04 -0700682
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700683 if (ENABLE_NATIVE_INPUT_DISPATCH) {
684 mInputManager.start();
685 } else {
686 mInputThread.start();
687 }
Romain Guy06882f82009-06-10 13:36:04 -0700688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 // Add ourself to the Watchdog monitors.
690 Watchdog.getInstance().addMonitor(this);
691 }
692
693 @Override
694 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
695 throws RemoteException {
696 try {
697 return super.onTransact(code, data, reply, flags);
698 } catch (RuntimeException e) {
699 // The window manager only throws security exceptions, so let's
700 // log all others.
701 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800702 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 }
704 throw e;
705 }
706 }
707
708 private void placeWindowAfter(Object pos, WindowState window) {
709 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800710 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 TAG, "Adding window " + window + " at "
712 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
713 mWindows.add(i+1, window);
714 }
715
716 private void placeWindowBefore(Object pos, WindowState window) {
717 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800718 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719 TAG, "Adding window " + window + " at "
720 + i + " of " + mWindows.size() + " (before " + pos + ")");
721 mWindows.add(i, window);
722 }
723
724 //This method finds out the index of a window that has the same app token as
725 //win. used for z ordering the windows in mWindows
726 private int findIdxBasedOnAppTokens(WindowState win) {
727 //use a local variable to cache mWindows
728 ArrayList localmWindows = mWindows;
729 int jmax = localmWindows.size();
730 if(jmax == 0) {
731 return -1;
732 }
733 for(int j = (jmax-1); j >= 0; j--) {
734 WindowState wentry = (WindowState)localmWindows.get(j);
735 if(wentry.mAppToken == win.mAppToken) {
736 return j;
737 }
738 }
739 return -1;
740 }
Romain Guy06882f82009-06-10 13:36:04 -0700741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
743 final IWindow client = win.mClient;
744 final WindowToken token = win.mToken;
745 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 final int N = localmWindows.size();
748 final WindowState attached = win.mAttachedWindow;
749 int i;
750 if (attached == null) {
751 int tokenWindowsPos = token.windows.size();
752 if (token.appWindowToken != null) {
753 int index = tokenWindowsPos-1;
754 if (index >= 0) {
755 // If this application has existing windows, we
756 // simply place the new window on top of them... but
757 // keep the starting window on top.
758 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
759 // Base windows go behind everything else.
760 placeWindowBefore(token.windows.get(0), win);
761 tokenWindowsPos = 0;
762 } else {
763 AppWindowToken atoken = win.mAppToken;
764 if (atoken != null &&
765 token.windows.get(index) == atoken.startingWindow) {
766 placeWindowBefore(token.windows.get(index), win);
767 tokenWindowsPos--;
768 } else {
769 int newIdx = findIdxBasedOnAppTokens(win);
770 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700771 //there is a window above this one associated with the same
772 //apptoken note that the window could be a floating window
773 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800775 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700776 TAG, "Adding window " + win + " at "
777 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 localmWindows.add(newIdx+1, win);
Romain Guy06882f82009-06-10 13:36:04 -0700779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 }
781 }
782 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800783 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 TAG, "Figuring out where to add app window "
785 + client.asBinder() + " (token=" + token + ")");
786 // Figure out where the window should go, based on the
787 // order of applications.
788 final int NA = mAppTokens.size();
789 Object pos = null;
790 for (i=NA-1; i>=0; i--) {
791 AppWindowToken t = mAppTokens.get(i);
792 if (t == token) {
793 i--;
794 break;
795 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800796
Dianne Hackborna8f60182009-09-01 19:01:50 -0700797 // We haven't reached the token yet; if this token
798 // is not going to the bottom and has windows, we can
799 // use it as an anchor for when we do reach the token.
800 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 pos = t.windows.get(0);
802 }
803 }
804 // We now know the index into the apps. If we found
805 // an app window above, that gives us the position; else
806 // we need to look some more.
807 if (pos != null) {
808 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700809 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 mTokenMap.get(((WindowState)pos).mClient.asBinder());
811 if (atoken != null) {
812 final int NC = atoken.windows.size();
813 if (NC > 0) {
814 WindowState bottom = atoken.windows.get(0);
815 if (bottom.mSubLayer < 0) {
816 pos = bottom;
817 }
818 }
819 }
820 placeWindowBefore(pos, win);
821 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700822 // Continue looking down until we find the first
823 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 while (i >= 0) {
825 AppWindowToken t = mAppTokens.get(i);
826 final int NW = t.windows.size();
827 if (NW > 0) {
828 pos = t.windows.get(NW-1);
829 break;
830 }
831 i--;
832 }
833 if (pos != null) {
834 // Move in front of any windows attached to this
835 // one.
836 WindowToken atoken =
837 mTokenMap.get(((WindowState)pos).mClient.asBinder());
838 if (atoken != null) {
839 final int NC = atoken.windows.size();
840 if (NC > 0) {
841 WindowState top = atoken.windows.get(NC-1);
842 if (top.mSubLayer >= 0) {
843 pos = top;
844 }
845 }
846 }
847 placeWindowAfter(pos, win);
848 } else {
849 // Just search for the start of this layer.
850 final int myLayer = win.mBaseLayer;
851 for (i=0; i<N; i++) {
852 WindowState w = (WindowState)localmWindows.get(i);
853 if (w.mBaseLayer > myLayer) {
854 break;
855 }
856 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800857 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700858 TAG, "Adding window " + win + " at "
859 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 localmWindows.add(i, win);
861 }
862 }
863 }
864 } else {
865 // Figure out where window should go, based on layer.
866 final int myLayer = win.mBaseLayer;
867 for (i=N-1; i>=0; i--) {
868 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
869 i++;
870 break;
871 }
872 }
873 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800874 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700875 TAG, "Adding window " + win + " at "
876 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 localmWindows.add(i, win);
878 }
879 if (addToToken) {
880 token.windows.add(tokenWindowsPos, win);
881 }
882
883 } else {
884 // Figure out this window's ordering relative to the window
885 // it is attached to.
886 final int NA = token.windows.size();
887 final int sublayer = win.mSubLayer;
888 int largestSublayer = Integer.MIN_VALUE;
889 WindowState windowWithLargestSublayer = null;
890 for (i=0; i<NA; i++) {
891 WindowState w = token.windows.get(i);
892 final int wSublayer = w.mSubLayer;
893 if (wSublayer >= largestSublayer) {
894 largestSublayer = wSublayer;
895 windowWithLargestSublayer = w;
896 }
897 if (sublayer < 0) {
898 // For negative sublayers, we go below all windows
899 // in the same sublayer.
900 if (wSublayer >= sublayer) {
901 if (addToToken) {
902 token.windows.add(i, win);
903 }
904 placeWindowBefore(
905 wSublayer >= 0 ? attached : w, win);
906 break;
907 }
908 } else {
909 // For positive sublayers, we go above all windows
910 // in the same sublayer.
911 if (wSublayer > sublayer) {
912 if (addToToken) {
913 token.windows.add(i, win);
914 }
915 placeWindowBefore(w, win);
916 break;
917 }
918 }
919 }
920 if (i >= NA) {
921 if (addToToken) {
922 token.windows.add(win);
923 }
924 if (sublayer < 0) {
925 placeWindowBefore(attached, win);
926 } else {
927 placeWindowAfter(largestSublayer >= 0
928 ? windowWithLargestSublayer
929 : attached,
930 win);
931 }
932 }
933 }
Romain Guy06882f82009-06-10 13:36:04 -0700934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 if (win.mAppToken != null && addToToken) {
936 win.mAppToken.allAppWindows.add(win);
937 }
938 }
Romain Guy06882f82009-06-10 13:36:04 -0700939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 static boolean canBeImeTarget(WindowState w) {
941 final int fl = w.mAttrs.flags
942 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
943 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
944 return w.isVisibleOrAdding();
945 }
946 return false;
947 }
Romain Guy06882f82009-06-10 13:36:04 -0700948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
950 final ArrayList localmWindows = mWindows;
951 final int N = localmWindows.size();
952 WindowState w = null;
953 int i = N;
954 while (i > 0) {
955 i--;
956 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700957
Joe Onorato8a9b2202010-02-26 18:56:32 -0800958 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 // + Integer.toHexString(w.mAttrs.flags));
960 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800961 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 // Yet more tricksyness! If this window is a "starting"
964 // window, we do actually want to be on top of it, but
965 // it is not -really- where input will go. So if the caller
966 // is not actually looking to move the IME, look down below
967 // for a real window to target...
968 if (!willMove
969 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
970 && i > 0) {
971 WindowState wb = (WindowState)localmWindows.get(i-1);
972 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
973 i--;
974 w = wb;
975 }
976 }
977 break;
978 }
979 }
Romain Guy06882f82009-06-10 13:36:04 -0700980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700982
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 if (willMove && w != null) {
987 final WindowState curTarget = mInputMethodTarget;
988 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 // Now some fun for dealing with window animations that
991 // modify the Z order. We need to look at all windows below
992 // the current target that are in this app, finding the highest
993 // visible one in layering.
994 AppWindowToken token = curTarget.mAppToken;
995 WindowState highestTarget = null;
996 int highestPos = 0;
997 if (token.animating || token.animation != null) {
998 int pos = 0;
999 pos = localmWindows.indexOf(curTarget);
1000 while (pos >= 0) {
1001 WindowState win = (WindowState)localmWindows.get(pos);
1002 if (win.mAppToken != token) {
1003 break;
1004 }
1005 if (!win.mRemoved) {
1006 if (highestTarget == null || win.mAnimLayer >
1007 highestTarget.mAnimLayer) {
1008 highestTarget = win;
1009 highestPos = pos;
1010 }
1011 }
1012 pos--;
1013 }
1014 }
Romain Guy06882f82009-06-10 13:36:04 -07001015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001017 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 + mNextAppTransition + " " + highestTarget
1019 + " animating=" + highestTarget.isAnimating()
1020 + " layer=" + highestTarget.mAnimLayer
1021 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001022
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001023 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 // If we are currently setting up for an animation,
1025 // hold everything until we can find out what will happen.
1026 mInputMethodTargetWaitingAnim = true;
1027 mInputMethodTarget = highestTarget;
1028 return highestPos + 1;
1029 } else if (highestTarget.isAnimating() &&
1030 highestTarget.mAnimLayer > w.mAnimLayer) {
1031 // If the window we are currently targeting is involved
1032 // with an animation, and it is on top of the next target
1033 // we will be over, then hold off on moving until
1034 // that is done.
1035 mInputMethodTarget = highestTarget;
1036 return highestPos + 1;
1037 }
1038 }
1039 }
1040 }
Romain Guy06882f82009-06-10 13:36:04 -07001041
Joe Onorato8a9b2202010-02-26 18:56:32 -08001042 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 if (w != null) {
1044 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001045 if (DEBUG_INPUT_METHOD) {
1046 RuntimeException e = null;
1047 if (!HIDE_STACK_CRAWLS) {
1048 e = new RuntimeException();
1049 e.fillInStackTrace();
1050 }
1051 Slog.w(TAG, "Moving IM target from "
1052 + mInputMethodTarget + " to " + w, e);
1053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 mInputMethodTarget = w;
1055 if (w.mAppToken != null) {
1056 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1057 } else {
1058 setInputMethodAnimLayerAdjustment(0);
1059 }
1060 }
1061 return i+1;
1062 }
1063 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001064 if (DEBUG_INPUT_METHOD) {
1065 RuntimeException e = null;
1066 if (!HIDE_STACK_CRAWLS) {
1067 e = new RuntimeException();
1068 e.fillInStackTrace();
1069 }
1070 Slog.w(TAG, "Moving IM target from "
1071 + mInputMethodTarget + " to null", e);
1072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 mInputMethodTarget = null;
1074 setInputMethodAnimLayerAdjustment(0);
1075 }
1076 return -1;
1077 }
Romain Guy06882f82009-06-10 13:36:04 -07001078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 void addInputMethodWindowToListLocked(WindowState win) {
1080 int pos = findDesiredInputMethodWindowIndexLocked(true);
1081 if (pos >= 0) {
1082 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001083 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001084 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 mWindows.add(pos, win);
1086 moveInputMethodDialogsLocked(pos+1);
1087 return;
1088 }
1089 win.mTargetAppToken = null;
1090 addWindowToListInOrderLocked(win, true);
1091 moveInputMethodDialogsLocked(pos);
1092 }
Romain Guy06882f82009-06-10 13:36:04 -07001093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001095 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 mInputMethodAnimLayerAdjustment = adj;
1097 WindowState imw = mInputMethodWindow;
1098 if (imw != null) {
1099 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001100 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 + " anim layer: " + imw.mAnimLayer);
1102 int wi = imw.mChildWindows.size();
1103 while (wi > 0) {
1104 wi--;
1105 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1106 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001107 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 + " anim layer: " + cw.mAnimLayer);
1109 }
1110 }
1111 int di = mInputMethodDialogs.size();
1112 while (di > 0) {
1113 di --;
1114 imw = mInputMethodDialogs.get(di);
1115 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001116 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 + " anim layer: " + imw.mAnimLayer);
1118 }
1119 }
Romain Guy06882f82009-06-10 13:36:04 -07001120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1122 int wpos = mWindows.indexOf(win);
1123 if (wpos >= 0) {
1124 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001125 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 mWindows.remove(wpos);
1127 int NC = win.mChildWindows.size();
1128 while (NC > 0) {
1129 NC--;
1130 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1131 int cpos = mWindows.indexOf(cw);
1132 if (cpos >= 0) {
1133 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001134 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001135 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 mWindows.remove(cpos);
1137 }
1138 }
1139 }
1140 return interestingPos;
1141 }
Romain Guy06882f82009-06-10 13:36:04 -07001142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 private void reAddWindowToListInOrderLocked(WindowState win) {
1144 addWindowToListInOrderLocked(win, false);
1145 // This is a hack to get all of the child windows added as well
1146 // at the right position. Child windows should be rare and
1147 // this case should be rare, so it shouldn't be that big a deal.
1148 int wpos = mWindows.indexOf(win);
1149 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001150 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001151 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 mWindows.remove(wpos);
1153 reAddWindowLocked(wpos, win);
1154 }
1155 }
Romain Guy06882f82009-06-10 13:36:04 -07001156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 void logWindowList(String prefix) {
1158 int N = mWindows.size();
1159 while (N > 0) {
1160 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001161 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 }
1163 }
Romain Guy06882f82009-06-10 13:36:04 -07001164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 void moveInputMethodDialogsLocked(int pos) {
1166 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001169 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 for (int i=0; i<N; i++) {
1171 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1172 }
1173 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001174 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 logWindowList(" ");
1176 }
Romain Guy06882f82009-06-10 13:36:04 -07001177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 if (pos >= 0) {
1179 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1180 if (pos < mWindows.size()) {
1181 WindowState wp = (WindowState)mWindows.get(pos);
1182 if (wp == mInputMethodWindow) {
1183 pos++;
1184 }
1185 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001186 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 for (int i=0; i<N; i++) {
1188 WindowState win = dialogs.get(i);
1189 win.mTargetAppToken = targetAppToken;
1190 pos = reAddWindowLocked(pos, win);
1191 }
1192 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001193 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 logWindowList(" ");
1195 }
1196 return;
1197 }
1198 for (int i=0; i<N; i++) {
1199 WindowState win = dialogs.get(i);
1200 win.mTargetAppToken = null;
1201 reAddWindowToListInOrderLocked(win);
1202 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001203 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001204 logWindowList(" ");
1205 }
1206 }
1207 }
Romain Guy06882f82009-06-10 13:36:04 -07001208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1210 final WindowState imWin = mInputMethodWindow;
1211 final int DN = mInputMethodDialogs.size();
1212 if (imWin == null && DN == 0) {
1213 return false;
1214 }
Romain Guy06882f82009-06-10 13:36:04 -07001215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1217 if (imPos >= 0) {
1218 // In this case, the input method windows are to be placed
1219 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 // First check to see if the input method windows are already
1222 // located here, and contiguous.
1223 final int N = mWindows.size();
1224 WindowState firstImWin = imPos < N
1225 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 // Figure out the actual input method window that should be
1228 // at the bottom of their stack.
1229 WindowState baseImWin = imWin != null
1230 ? imWin : mInputMethodDialogs.get(0);
1231 if (baseImWin.mChildWindows.size() > 0) {
1232 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1233 if (cw.mSubLayer < 0) baseImWin = cw;
1234 }
Romain Guy06882f82009-06-10 13:36:04 -07001235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 if (firstImWin == baseImWin) {
1237 // The windows haven't moved... but are they still contiguous?
1238 // First find the top IM window.
1239 int pos = imPos+1;
1240 while (pos < N) {
1241 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1242 break;
1243 }
1244 pos++;
1245 }
1246 pos++;
1247 // Now there should be no more input method windows above.
1248 while (pos < N) {
1249 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1250 break;
1251 }
1252 pos++;
1253 }
1254 if (pos >= N) {
1255 // All is good!
1256 return false;
1257 }
1258 }
Romain Guy06882f82009-06-10 13:36:04 -07001259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 if (imWin != null) {
1261 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001262 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 logWindowList(" ");
1264 }
1265 imPos = tmpRemoveWindowLocked(imPos, imWin);
1266 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001267 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 logWindowList(" ");
1269 }
1270 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1271 reAddWindowLocked(imPos, imWin);
1272 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001273 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 logWindowList(" ");
1275 }
1276 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1277 } else {
1278 moveInputMethodDialogsLocked(imPos);
1279 }
Romain Guy06882f82009-06-10 13:36:04 -07001280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 } else {
1282 // In this case, the input method windows go in a fixed layer,
1283 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001286 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 tmpRemoveWindowLocked(0, imWin);
1288 imWin.mTargetAppToken = null;
1289 reAddWindowToListInOrderLocked(imWin);
1290 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001291 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 logWindowList(" ");
1293 }
1294 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1295 } else {
1296 moveInputMethodDialogsLocked(-1);;
1297 }
Romain Guy06882f82009-06-10 13:36:04 -07001298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 }
Romain Guy06882f82009-06-10 13:36:04 -07001300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 if (needAssignLayers) {
1302 assignLayersLocked();
1303 }
Romain Guy06882f82009-06-10 13:36:04 -07001304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 return true;
1306 }
Romain Guy06882f82009-06-10 13:36:04 -07001307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 void adjustInputMethodDialogsLocked() {
1309 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1310 }
Romain Guy06882f82009-06-10 13:36:04 -07001311
Dianne Hackborn25994b42009-09-04 14:21:19 -07001312 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001313 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001314 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1315 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1316 ? wallpaperTarget.mAppToken.animation : null)
1317 + " upper=" + mUpperWallpaperTarget
1318 + " lower=" + mLowerWallpaperTarget);
1319 return (wallpaperTarget != null
1320 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1321 && wallpaperTarget.mAppToken.animation != null)))
1322 || mUpperWallpaperTarget != null
1323 || mLowerWallpaperTarget != null;
1324 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001325
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001326 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1327 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001328
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001329 int adjustWallpaperWindowsLocked() {
1330 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001331
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001332 final int dw = mDisplay.getWidth();
1333 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001334
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001335 // First find top-most window that has asked to be on top of the
1336 // wallpaper; all wallpapers go behind it.
1337 final ArrayList localmWindows = mWindows;
1338 int N = localmWindows.size();
1339 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001340 WindowState foundW = null;
1341 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001342 WindowState topCurW = null;
1343 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001344 int i = N;
1345 while (i > 0) {
1346 i--;
1347 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001348 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1349 if (topCurW == null) {
1350 topCurW = w;
1351 topCurI = i;
1352 }
1353 continue;
1354 }
1355 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001356 if (w.mAppToken != null) {
1357 // If this window's app token is hidden and not animating,
1358 // it is of no interest to us.
1359 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001360 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001361 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001362 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001363 continue;
1364 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001365 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001366 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001367 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1368 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001369 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001370 && (mWallpaperTarget == w
1371 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001372 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001373 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001374 foundW = w;
1375 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001376 if (w == mWallpaperTarget && ((w.mAppToken != null
1377 && w.mAppToken.animation != null)
1378 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001379 // The current wallpaper target is animating, so we'll
1380 // look behind it for another possible target and figure
1381 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001382 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001383 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001384 continue;
1385 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001386 break;
1387 }
1388 }
1389
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001390 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001391 // If we are currently waiting for an app transition, and either
1392 // the current target or the next target are involved with it,
1393 // then hold off on doing anything with the wallpaper.
1394 // Note that we are checking here for just whether the target
1395 // is part of an app token... which is potentially overly aggressive
1396 // (the app token may not be involved in the transition), but good
1397 // enough (we'll just wait until whatever transition is pending
1398 // executes).
1399 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001400 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001401 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001402 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001403 }
1404 if (foundW != null && foundW.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 found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001407 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001408 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001409 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001410
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001411 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001412 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001413 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001414 + " oldTarget: " + mWallpaperTarget);
1415 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001416
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001417 mLowerWallpaperTarget = null;
1418 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001419
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001420 WindowState oldW = mWallpaperTarget;
1421 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001422
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001423 // Now what is happening... if the current and new targets are
1424 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001425 if (foundW != null && oldW != null) {
1426 boolean oldAnim = oldW.mAnimation != null
1427 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1428 boolean foundAnim = foundW.mAnimation != null
1429 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001430 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001431 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001432 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001433 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001434 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001435 int oldI = localmWindows.indexOf(oldW);
1436 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001438 }
1439 if (oldI >= 0) {
1440 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001441 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001442 + "=" + oldW + "; new#" + foundI
1443 + "=" + foundW);
1444 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001445
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001446 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001447 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001448 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001449 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001450 }
1451 mWallpaperTarget = oldW;
1452 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001453
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001454 // Now set the upper and lower wallpaper targets
1455 // correctly, and make sure that we are positioning
1456 // the wallpaper below the lower.
1457 if (foundI > oldI) {
1458 // The new target is on top of the old one.
1459 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001460 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001461 }
1462 mUpperWallpaperTarget = foundW;
1463 mLowerWallpaperTarget = oldW;
1464 foundW = oldW;
1465 foundI = oldI;
1466 } else {
1467 // The new target is below the old one.
1468 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001469 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001470 }
1471 mUpperWallpaperTarget = oldW;
1472 mLowerWallpaperTarget = foundW;
1473 }
1474 }
1475 }
1476 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001477
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001478 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001479 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001480 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1481 || (mLowerWallpaperTarget.mAppToken != null
1482 && mLowerWallpaperTarget.mAppToken.animation != null);
1483 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1484 || (mUpperWallpaperTarget.mAppToken != null
1485 && mUpperWallpaperTarget.mAppToken.animation != null);
1486 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001487 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001488 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001489 }
1490 mLowerWallpaperTarget = null;
1491 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001492 }
1493 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001494
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001495 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001496 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001497 // The window is visible to the compositor... but is it visible
1498 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001499 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001500 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001501
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001502 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001503 // its layer adjustment. Only do this if we are not transfering
1504 // between two wallpaper targets.
1505 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001506 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001507 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001508
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001509 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1510 * TYPE_LAYER_MULTIPLIER
1511 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001512
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001513 // Now w is the window we are supposed to be behind... but we
1514 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001515 // AND any starting window associated with it, AND below the
1516 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001517 while (foundI > 0) {
1518 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001519 if (wb.mBaseLayer < maxLayer &&
1520 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001521 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001522 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001523 // This window is not related to the previous one in any
1524 // interesting way, so stop here.
1525 break;
1526 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001527 foundW = wb;
1528 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001529 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001530 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001531 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001532 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001533
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001534 if (foundW == null && topCurW != null) {
1535 // There is no wallpaper target, so it goes at the bottom.
1536 // We will assume it is the same place as last time, if known.
1537 foundW = topCurW;
1538 foundI = topCurI+1;
1539 } else {
1540 // Okay i is the position immediately above the wallpaper. Look at
1541 // what is below it for later.
1542 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1543 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001544
Dianne Hackborn284ac932009-08-28 10:34:25 -07001545 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001546 if (mWallpaperTarget.mWallpaperX >= 0) {
1547 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001548 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001549 }
1550 if (mWallpaperTarget.mWallpaperY >= 0) {
1551 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001552 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001553 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001554 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001555
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001556 // Start stepping backwards from here, ensuring that our wallpaper windows
1557 // are correctly placed.
1558 int curTokenIndex = mWallpaperTokens.size();
1559 while (curTokenIndex > 0) {
1560 curTokenIndex--;
1561 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001562 if (token.hidden == visible) {
1563 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1564 token.hidden = !visible;
1565 // Need to do a layout to ensure the wallpaper now has the
1566 // correct size.
1567 mLayoutNeeded = true;
1568 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001569
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001570 int curWallpaperIndex = token.windows.size();
1571 while (curWallpaperIndex > 0) {
1572 curWallpaperIndex--;
1573 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001574
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001575 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001576 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001577 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001578
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001579 // First, make sure the client has the current visibility
1580 // state.
1581 if (wallpaper.mWallpaperVisible != visible) {
1582 wallpaper.mWallpaperVisible = visible;
1583 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001584 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001585 "Setting visibility of wallpaper " + wallpaper
1586 + ": " + visible);
1587 wallpaper.mClient.dispatchAppVisibility(visible);
1588 } catch (RemoteException e) {
1589 }
1590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001591
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001592 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001593 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001594 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001595
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001596 // First, if this window is at the current index, then all
1597 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001598 if (wallpaper == foundW) {
1599 foundI--;
1600 foundW = foundI > 0
1601 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001602 continue;
1603 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001604
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001605 // The window didn't match... the current wallpaper window,
1606 // wherever it is, is in the wrong place, so make sure it is
1607 // not in the list.
1608 int oldIndex = localmWindows.indexOf(wallpaper);
1609 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001610 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001611 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001612 localmWindows.remove(oldIndex);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001613 if (oldIndex < foundI) {
1614 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001615 }
1616 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001617
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001618 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001619 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001620 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001621 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001622
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001623 localmWindows.add(foundI, wallpaper);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001624 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001625 }
1626 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001627
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001628 return changed;
1629 }
1630
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001631 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001632 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001633 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001634 mWallpaperAnimLayerAdjustment = adj;
1635 int curTokenIndex = mWallpaperTokens.size();
1636 while (curTokenIndex > 0) {
1637 curTokenIndex--;
1638 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1639 int curWallpaperIndex = token.windows.size();
1640 while (curWallpaperIndex > 0) {
1641 curWallpaperIndex--;
1642 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1643 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001644 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001645 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001646 }
1647 }
1648 }
1649
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001650 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1651 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001652 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001653 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001654 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001655 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001656 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1657 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1658 changed = wallpaperWin.mXOffset != offset;
1659 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001660 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001661 + wallpaperWin + " x: " + offset);
1662 wallpaperWin.mXOffset = offset;
1663 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001664 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001665 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001666 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001667 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001668 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001669
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001670 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001671 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001672 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1673 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1674 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001675 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001676 + wallpaperWin + " y: " + offset);
1677 changed = true;
1678 wallpaperWin.mYOffset = offset;
1679 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001680 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001681 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001682 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001683 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001684 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001685
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001686 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001687 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001688 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001689 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1690 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001691 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001692 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001693 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001694 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001695 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1696 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001697 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001698 if (mWaitingOnWallpaper != null) {
1699 long start = SystemClock.uptimeMillis();
1700 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1701 < start) {
1702 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001703 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001704 "Waiting for offset complete...");
1705 mWindowMap.wait(WALLPAPER_TIMEOUT);
1706 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001707 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001708 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001709 if ((start+WALLPAPER_TIMEOUT)
1710 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001712 + wallpaperWin);
1713 mLastWallpaperTimeoutTime = start;
1714 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001715 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001716 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001717 }
1718 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001719 } catch (RemoteException e) {
1720 }
1721 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001722
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001723 return changed;
1724 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001725
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001726 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001727 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001728 if (mWaitingOnWallpaper != null &&
1729 mWaitingOnWallpaper.mClient.asBinder() == window) {
1730 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001731 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001732 }
1733 }
1734 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001735
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001736 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001737 final int dw = mDisplay.getWidth();
1738 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001739
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001740 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001741
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001742 WindowState target = mWallpaperTarget;
1743 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001744 if (target.mWallpaperX >= 0) {
1745 mLastWallpaperX = target.mWallpaperX;
1746 } else if (changingTarget.mWallpaperX >= 0) {
1747 mLastWallpaperX = changingTarget.mWallpaperX;
1748 }
1749 if (target.mWallpaperY >= 0) {
1750 mLastWallpaperY = target.mWallpaperY;
1751 } else if (changingTarget.mWallpaperY >= 0) {
1752 mLastWallpaperY = changingTarget.mWallpaperY;
1753 }
1754 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001755
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001756 int curTokenIndex = mWallpaperTokens.size();
1757 while (curTokenIndex > 0) {
1758 curTokenIndex--;
1759 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1760 int curWallpaperIndex = token.windows.size();
1761 while (curWallpaperIndex > 0) {
1762 curWallpaperIndex--;
1763 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1764 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1765 wallpaper.computeShownFrameLocked();
1766 changed = true;
1767 // We only want to be synchronous with one wallpaper.
1768 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001769 }
1770 }
1771 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001772
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001773 return changed;
1774 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001775
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001776 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001777 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001778 final int dw = mDisplay.getWidth();
1779 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001781 int curTokenIndex = mWallpaperTokens.size();
1782 while (curTokenIndex > 0) {
1783 curTokenIndex--;
1784 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001785 if (token.hidden == visible) {
1786 token.hidden = !visible;
1787 // Need to do a layout to ensure the wallpaper now has the
1788 // correct size.
1789 mLayoutNeeded = true;
1790 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001791
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001792 int curWallpaperIndex = token.windows.size();
1793 while (curWallpaperIndex > 0) {
1794 curWallpaperIndex--;
1795 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1796 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001797 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001798 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001799
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001800 if (wallpaper.mWallpaperVisible != visible) {
1801 wallpaper.mWallpaperVisible = visible;
1802 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001803 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001804 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001805 + ": " + visible);
1806 wallpaper.mClient.dispatchAppVisibility(visible);
1807 } catch (RemoteException e) {
1808 }
1809 }
1810 }
1811 }
1812 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001813
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001814 void sendPointerToWallpaperLocked(WindowState srcWin,
1815 MotionEvent pointer, long eventTime) {
1816 int curTokenIndex = mWallpaperTokens.size();
1817 while (curTokenIndex > 0) {
1818 curTokenIndex--;
1819 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1820 int curWallpaperIndex = token.windows.size();
1821 while (curWallpaperIndex > 0) {
1822 curWallpaperIndex--;
1823 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1824 if ((wallpaper.mAttrs.flags &
1825 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
1826 continue;
1827 }
1828 try {
1829 MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
Dianne Hackborn6adba242009-11-10 11:10:09 -08001830 if (srcWin != null) {
1831 ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
1832 srcWin.mFrame.top-wallpaper.mFrame.top);
1833 } else {
1834 ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
1835 }
1836 switch (pointer.getAction()) {
1837 case MotionEvent.ACTION_DOWN:
1838 mSendingPointersToWallpaper = true;
1839 break;
1840 case MotionEvent.ACTION_UP:
1841 mSendingPointersToWallpaper = false;
1842 break;
1843 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001844 wallpaper.mClient.dispatchPointer(ev, eventTime, false);
1845 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001846 Slog.w(TAG, "Failure sending pointer to wallpaper", e);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001847 }
1848 }
1849 }
1850 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001851
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001852 void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
1853 MotionEvent pointer, long eventTime, boolean skipped) {
1854 if (relWin != null) {
1855 mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
1856 } else {
1857 mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
1858 }
1859
1860 // If we sent an initial down to the wallpaper, then continue
1861 // sending events until the final up.
1862 if (mSendingPointersToWallpaper) {
1863 if (skipped) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.i(TAG, "Sending skipped pointer to wallpaper!");
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001865 }
1866 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1867
1868 // If we are on top of the wallpaper, then the wallpaper also
1869 // gets to see this movement.
1870 } else if (srcWin != null
1871 && pointer.getAction() == MotionEvent.ACTION_DOWN
1872 && mWallpaperTarget == srcWin
1873 && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
1874 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1875 }
1876 }
1877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 public int addWindow(Session session, IWindow client,
1879 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001880 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 int res = mPolicy.checkAddPermission(attrs);
1882 if (res != WindowManagerImpl.ADD_OKAY) {
1883 return res;
1884 }
Romain Guy06882f82009-06-10 13:36:04 -07001885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 boolean reportNewConfig = false;
1887 WindowState attachedWindow = null;
1888 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 synchronized(mWindowMap) {
1891 // Instantiating a Display requires talking with the simulator,
1892 // so don't do it until we know the system is mostly up and
1893 // running.
1894 if (mDisplay == null) {
1895 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1896 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001897 mInitialDisplayWidth = mDisplay.getWidth();
1898 mInitialDisplayHeight = mDisplay.getHeight();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001899 if (ENABLE_NATIVE_INPUT_DISPATCH) {
1900 mInputManager.setDisplaySize(0,
1901 mInitialDisplayWidth, mInitialDisplayHeight);
1902 } else {
1903 mQueue.setDisplay(mDisplay);
1904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905 reportNewConfig = true;
1906 }
Romain Guy06882f82009-06-10 13:36:04 -07001907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001909 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1911 }
1912
1913 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001914 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001916 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001917 + attrs.token + ". Aborting.");
1918 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1919 }
1920 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1921 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 + attrs.token + ". Aborting.");
1924 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1925 }
1926 }
1927
1928 boolean addToken = false;
1929 WindowToken token = mTokenMap.get(attrs.token);
1930 if (token == null) {
1931 if (attrs.type >= FIRST_APPLICATION_WINDOW
1932 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001933 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 + attrs.token + ". Aborting.");
1935 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1936 }
1937 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001938 Slog.w(TAG, "Attempted to add input method 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 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001942 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001943 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001944 + attrs.token + ". Aborting.");
1945 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947 token = new WindowToken(attrs.token, -1, false);
1948 addToken = true;
1949 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1950 && attrs.type <= LAST_APPLICATION_WINDOW) {
1951 AppWindowToken atoken = token.appWindowToken;
1952 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001953 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 + token + ". Aborting.");
1955 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1956 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001957 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 + token + ". Aborting.");
1959 return WindowManagerImpl.ADD_APP_EXITING;
1960 }
1961 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1962 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001963 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1965 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1966 }
1967 } else if (attrs.type == TYPE_INPUT_METHOD) {
1968 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001969 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 + attrs.token + ". Aborting.");
1971 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1972 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001973 } else if (attrs.type == TYPE_WALLPAPER) {
1974 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001975 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001976 + attrs.token + ". Aborting.");
1977 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
1980
1981 win = new WindowState(session, client, token,
1982 attachedWindow, attrs, viewVisibility);
1983 if (win.mDeathRecipient == null) {
1984 // Client has apparently died, so there is no reason to
1985 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001986 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 + " that is dead, aborting.");
1988 return WindowManagerImpl.ADD_APP_EXITING;
1989 }
1990
1991 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 res = mPolicy.prepareAddWindowLw(win, attrs);
1994 if (res != WindowManagerImpl.ADD_OKAY) {
1995 return res;
1996 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001997
1998 if (ENABLE_NATIVE_INPUT_DISPATCH) {
1999 if (outInputChannel != null) {
2000 String name = win.makeInputChannelName();
2001 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2002 win.mInputChannel = inputChannels[0];
2003 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2004
2005 mInputManager.registerInputChannel(win.mInputChannel);
2006 }
2007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008
2009 // From now on, no exceptions or errors allowed!
2010
2011 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 if (addToken) {
2016 mTokenMap.put(attrs.token, token);
2017 mTokenList.add(token);
2018 }
2019 win.attach();
2020 mWindowMap.put(client.asBinder(), win);
2021
2022 if (attrs.type == TYPE_APPLICATION_STARTING &&
2023 token.appWindowToken != null) {
2024 token.appWindowToken.startingWindow = win;
2025 }
2026
2027 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 if (attrs.type == TYPE_INPUT_METHOD) {
2030 mInputMethodWindow = win;
2031 addInputMethodWindowToListLocked(win);
2032 imMayMove = false;
2033 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2034 mInputMethodDialogs.add(win);
2035 addWindowToListInOrderLocked(win, true);
2036 adjustInputMethodDialogsLocked();
2037 imMayMove = false;
2038 } else {
2039 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002040 if (attrs.type == TYPE_WALLPAPER) {
2041 mLastWallpaperTimeoutTime = 0;
2042 adjustWallpaperWindowsLocked();
2043 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002044 adjustWallpaperWindowsLocked();
2045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002046 }
Romain Guy06882f82009-06-10 13:36:04 -07002047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002050 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 if (mInTouchMode) {
2053 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2054 }
2055 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2056 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2057 }
Romain Guy06882f82009-06-10 13:36:04 -07002058
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002059 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 if (win.canReceiveKeys()) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002061 if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
2062 == true) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002063 imMayMove = false;
2064 }
2065 }
Romain Guy06882f82009-06-10 13:36:04 -07002066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002067 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002068 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 }
Romain Guy06882f82009-06-10 13:36:04 -07002070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002071 assignLayersLocked();
2072 // Don't do layout here, the window must call
2073 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 //dump();
2076
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002077 if (focusChanged) {
2078 if (mCurrentFocus != null) {
2079 mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
2080 }
2081 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002082 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 TAG, "New client " + client.asBinder()
2084 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002085
2086 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2087 reportNewConfig = true;
2088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089 }
2090
2091 // sendNewConfiguration() checks caller permissions so we must call it with
2092 // privilege. updateOrientationFromAppTokens() clears and resets the caller
2093 // identity anyway, so it's safe to just clear & restore around this whole
2094 // block.
2095 final long origId = Binder.clearCallingIdentity();
2096 if (reportNewConfig) {
2097 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002098 }
2099 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 return res;
2102 }
Romain Guy06882f82009-06-10 13:36:04 -07002103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002104 public void removeWindow(Session session, IWindow client) {
2105 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002106 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 if (win == null) {
2108 return;
2109 }
2110 removeWindowLocked(session, win);
2111 }
2112 }
Romain Guy06882f82009-06-10 13:36:04 -07002113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 public void removeWindowLocked(Session session, WindowState win) {
2115
Joe Onorato8a9b2202010-02-26 18:56:32 -08002116 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 TAG, "Remove " + win + " client="
2118 + Integer.toHexString(System.identityHashCode(
2119 win.mClient.asBinder()))
2120 + ", surface=" + win.mSurface);
2121
2122 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002123
Joe Onorato8a9b2202010-02-26 18:56:32 -08002124 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2126 + " mExiting=" + win.mExiting
2127 + " isAnimating=" + win.isAnimating()
2128 + " app-animation="
2129 + (win.mAppToken != null ? win.mAppToken.animation : null)
2130 + " inPendingTransaction="
2131 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2132 + " mDisplayFrozen=" + mDisplayFrozen);
2133 // Visibility of the removed window. Will be used later to update orientation later on.
2134 boolean wasVisible = false;
2135 // First, see if we need to run an animation. If we do, we have
2136 // to hold off on removing the window until the animation is done.
2137 // If the display is frozen, just remove immediately, since the
2138 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002139 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 // If we are not currently running the exit animation, we
2141 // need to see about starting one.
2142 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2145 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2146 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2147 }
2148 // Try starting an animation.
2149 if (applyAnimationLocked(win, transit, false)) {
2150 win.mExiting = true;
2151 }
2152 }
2153 if (win.mExiting || win.isAnimating()) {
2154 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002155 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 win.mExiting = true;
2157 win.mRemoveOnExit = true;
2158 mLayoutNeeded = true;
2159 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2160 performLayoutAndPlaceSurfacesLocked();
2161 if (win.mAppToken != null) {
2162 win.mAppToken.updateReportedVisibilityLocked();
2163 }
2164 //dump();
2165 Binder.restoreCallingIdentity(origId);
2166 return;
2167 }
2168 }
2169
2170 removeWindowInnerLocked(session, win);
2171 // Removing a visible window will effect the computed orientation
2172 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002173 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002174 != mForcedAppOrientation
2175 && updateOrientationFromAppTokensLocked()) {
2176 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177 }
2178 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2179 Binder.restoreCallingIdentity(origId);
2180 }
Romain Guy06882f82009-06-10 13:36:04 -07002181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07002183 mKeyWaiter.finishedKey(session, win.mClient, true,
2184 KeyWaiter.RETURN_NOTHING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 mKeyWaiter.releasePendingPointerLocked(win.mSession);
2186 mKeyWaiter.releasePendingTrackballLocked(win.mSession);
Romain Guy06882f82009-06-10 13:36:04 -07002187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 if (mInputMethodTarget == win) {
2191 moveInputMethodWindowsIfNeededLocked(false);
2192 }
Romain Guy06882f82009-06-10 13:36:04 -07002193
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002194 if (false) {
2195 RuntimeException e = new RuntimeException("here");
2196 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002197 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002198 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002200 mPolicy.removeWindowLw(win);
2201 win.removeLocked();
2202
2203 mWindowMap.remove(win.mClient.asBinder());
2204 mWindows.remove(win);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002205 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206
2207 if (mInputMethodWindow == win) {
2208 mInputMethodWindow = null;
2209 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2210 mInputMethodDialogs.remove(win);
2211 }
Romain Guy06882f82009-06-10 13:36:04 -07002212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 final WindowToken token = win.mToken;
2214 final AppWindowToken atoken = win.mAppToken;
2215 token.windows.remove(win);
2216 if (atoken != null) {
2217 atoken.allAppWindows.remove(win);
2218 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002219 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220 TAG, "**** Removing window " + win + ": count="
2221 + token.windows.size());
2222 if (token.windows.size() == 0) {
2223 if (!token.explicit) {
2224 mTokenMap.remove(token.token);
2225 mTokenList.remove(token);
2226 } else if (atoken != null) {
2227 atoken.firstWindowDrawn = false;
2228 }
2229 }
2230
2231 if (atoken != null) {
2232 if (atoken.startingWindow == win) {
2233 atoken.startingWindow = null;
2234 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2235 // If this is the last window and we had requested a starting
2236 // transition window, well there is no point now.
2237 atoken.startingData = null;
2238 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2239 // If this is the last window except for a starting transition
2240 // window, we need to get rid of the starting transition.
2241 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002242 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 + ": no more real windows");
2244 }
2245 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2246 mH.sendMessage(m);
2247 }
2248 }
Romain Guy06882f82009-06-10 13:36:04 -07002249
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002250 if (win.mAttrs.type == TYPE_WALLPAPER) {
2251 mLastWallpaperTimeoutTime = 0;
2252 adjustWallpaperWindowsLocked();
2253 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002254 adjustWallpaperWindowsLocked();
2255 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 if (!mInLayout) {
2258 assignLayersLocked();
2259 mLayoutNeeded = true;
2260 performLayoutAndPlaceSurfacesLocked();
2261 if (win.mAppToken != null) {
2262 win.mAppToken.updateReportedVisibilityLocked();
2263 }
2264 }
2265 }
2266
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002267 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2268 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2269 + ": " + msg + " / " + w.mAttrs.getTitle();
2270 if (where != null) {
2271 Slog.i(TAG, str, where);
2272 } else {
2273 Slog.i(TAG, str);
2274 }
2275 }
2276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2278 long origId = Binder.clearCallingIdentity();
2279 try {
2280 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002281 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002283 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 Surface.openTransaction();
2285 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002286 if (SHOW_TRANSACTIONS) logSurface(w,
2287 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 w.mSurface.setTransparentRegionHint(region);
2289 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002290 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 Surface.closeTransaction();
2292 }
2293 }
2294 }
2295 } finally {
2296 Binder.restoreCallingIdentity(origId);
2297 }
2298 }
2299
2300 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002301 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 Rect visibleInsets) {
2303 long origId = Binder.clearCallingIdentity();
2304 try {
2305 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002306 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 if (w != null) {
2308 w.mGivenInsetsPending = false;
2309 w.mGivenContentInsets.set(contentInsets);
2310 w.mGivenVisibleInsets.set(visibleInsets);
2311 w.mTouchableInsets = touchableInsets;
2312 mLayoutNeeded = true;
2313 performLayoutAndPlaceSurfacesLocked();
2314 }
2315 }
2316 } finally {
2317 Binder.restoreCallingIdentity(origId);
2318 }
2319 }
Romain Guy06882f82009-06-10 13:36:04 -07002320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 public void getWindowDisplayFrame(Session session, IWindow client,
2322 Rect outDisplayFrame) {
2323 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002324 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 if (win == null) {
2326 outDisplayFrame.setEmpty();
2327 return;
2328 }
2329 outDisplayFrame.set(win.mDisplayFrame);
2330 }
2331 }
2332
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002333 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2334 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002335 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2336 window.mWallpaperX = x;
2337 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002338 window.mWallpaperXStep = xStep;
2339 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002340 if (updateWallpaperOffsetLocked(window, true)) {
2341 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002342 }
2343 }
2344 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002345
Dianne Hackborn75804932009-10-20 20:15:20 -07002346 void wallpaperCommandComplete(IBinder window, Bundle result) {
2347 synchronized (mWindowMap) {
2348 if (mWaitingOnWallpaper != null &&
2349 mWaitingOnWallpaper.mClient.asBinder() == window) {
2350 mWaitingOnWallpaper = null;
2351 mWindowMap.notifyAll();
2352 }
2353 }
2354 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002355
Dianne Hackborn75804932009-10-20 20:15:20 -07002356 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2357 String action, int x, int y, int z, Bundle extras, boolean sync) {
2358 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2359 || window == mUpperWallpaperTarget) {
2360 boolean doWait = sync;
2361 int curTokenIndex = mWallpaperTokens.size();
2362 while (curTokenIndex > 0) {
2363 curTokenIndex--;
2364 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2365 int curWallpaperIndex = token.windows.size();
2366 while (curWallpaperIndex > 0) {
2367 curWallpaperIndex--;
2368 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2369 try {
2370 wallpaper.mClient.dispatchWallpaperCommand(action,
2371 x, y, z, extras, sync);
2372 // We only want to be synchronous with one wallpaper.
2373 sync = false;
2374 } catch (RemoteException e) {
2375 }
2376 }
2377 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002378
Dianne Hackborn75804932009-10-20 20:15:20 -07002379 if (doWait) {
2380 // XXX Need to wait for result.
2381 }
2382 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002383
Dianne Hackborn75804932009-10-20 20:15:20 -07002384 return null;
2385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 public int relayoutWindow(Session session, IWindow client,
2388 WindowManager.LayoutParams attrs, int requestedWidth,
2389 int requestedHeight, int viewVisibility, boolean insetsPending,
2390 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002391 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 boolean displayed = false;
2393 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002394 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002398 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 if (win == null) {
2400 return 0;
2401 }
2402 win.mRequestedWidth = requestedWidth;
2403 win.mRequestedHeight = requestedHeight;
2404
2405 if (attrs != null) {
2406 mPolicy.adjustWindowParamsLw(attrs);
2407 }
Romain Guy06882f82009-06-10 13:36:04 -07002408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 int attrChanges = 0;
2410 int flagChanges = 0;
2411 if (attrs != null) {
2412 flagChanges = win.mAttrs.flags ^= attrs.flags;
2413 attrChanges = win.mAttrs.copyFrom(attrs);
2414 }
2415
Joe Onorato8a9b2202010-02-26 18:56:32 -08002416 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417
2418 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2419 win.mAlpha = attrs.alpha;
2420 }
2421
2422 final boolean scaledWindow =
2423 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2424
2425 if (scaledWindow) {
2426 // requested{Width|Height} Surface's physical size
2427 // attrs.{width|height} Size on screen
2428 win.mHScale = (attrs.width != requestedWidth) ?
2429 (attrs.width / (float)requestedWidth) : 1.0f;
2430 win.mVScale = (attrs.height != requestedHeight) ?
2431 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002432 } else {
2433 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 }
2435
2436 boolean imMayMove = (flagChanges&(
2437 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2438 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 boolean focusMayChange = win.mViewVisibility != viewVisibility
2441 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2442 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002443
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002444 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2445 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 win.mRelayoutCalled = true;
2448 final int oldVisibility = win.mViewVisibility;
2449 win.mViewVisibility = viewVisibility;
2450 if (viewVisibility == View.VISIBLE &&
2451 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2452 displayed = !win.isVisibleLw();
2453 if (win.mExiting) {
2454 win.mExiting = false;
2455 win.mAnimation = null;
2456 }
2457 if (win.mDestroying) {
2458 win.mDestroying = false;
2459 mDestroySurface.remove(win);
2460 }
2461 if (oldVisibility == View.GONE) {
2462 win.mEnterAnimationPending = true;
2463 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002464 if (displayed) {
2465 if (win.mSurface != null && !win.mDrawPending
2466 && !win.mCommitDrawPending && !mDisplayFrozen
2467 && mPolicy.isScreenOn()) {
2468 applyEnterAnimationLocked(win);
2469 }
2470 if ((win.mAttrs.flags
2471 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2472 if (DEBUG_VISIBILITY) Slog.v(TAG,
2473 "Relayout window turning screen on: " + win);
2474 win.mTurnOnScreen = true;
2475 }
2476 int diff = 0;
2477 if (win.mConfiguration != mCurConfiguration
2478 && (win.mConfiguration == null
2479 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2480 win.mConfiguration = mCurConfiguration;
2481 if (DEBUG_CONFIGURATION) {
2482 Slog.i(TAG, "Window " + win + " visible with new config: "
2483 + win.mConfiguration + " / 0x"
2484 + Integer.toHexString(diff));
2485 }
2486 outConfig.setTo(mCurConfiguration);
2487 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2490 // To change the format, we need to re-build the surface.
2491 win.destroySurfaceLocked();
2492 displayed = true;
2493 }
2494 try {
2495 Surface surface = win.createSurfaceLocked();
2496 if (surface != null) {
2497 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002498 win.mReportDestroySurface = false;
2499 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002500 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002501 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002503 // For some reason there isn't a surface. Clear the
2504 // caller's object so they see the same state.
2505 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 }
2507 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002508 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002509 + client + " (" + win.mAttrs.getTitle() + ")",
2510 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 Binder.restoreCallingIdentity(origId);
2512 return 0;
2513 }
2514 if (displayed) {
2515 focusMayChange = true;
2516 }
2517 if (win.mAttrs.type == TYPE_INPUT_METHOD
2518 && mInputMethodWindow == null) {
2519 mInputMethodWindow = win;
2520 imMayMove = true;
2521 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002522 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2523 && win.mAppToken != null
2524 && win.mAppToken.startingWindow != null) {
2525 // Special handling of starting window over the base
2526 // window of the app: propagate lock screen flags to it,
2527 // to provide the correct semantics while starting.
2528 final int mask =
2529 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002530 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2531 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002532 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2533 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002535 } else {
2536 win.mEnterAnimationPending = false;
2537 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002538 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002539 + ": mExiting=" + win.mExiting
2540 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 // If we are not currently running the exit animation, we
2542 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002543 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 // Try starting an animation; if there isn't one, we
2545 // can destroy the surface right away.
2546 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2547 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2548 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2549 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002550 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002551 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002552 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 win.mExiting = true;
2554 mKeyWaiter.finishedKey(session, client, true,
2555 KeyWaiter.RETURN_NOTHING);
2556 } else if (win.isAnimating()) {
2557 // Currently in a hide animation... turn this into
2558 // an exit.
2559 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002560 } else if (win == mWallpaperTarget) {
2561 // If the wallpaper is currently behind this
2562 // window, we need to change both of them inside
2563 // of a transaction to avoid artifacts.
2564 win.mExiting = true;
2565 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 } else {
2567 if (mInputMethodWindow == win) {
2568 mInputMethodWindow = null;
2569 }
2570 win.destroySurfaceLocked();
2571 }
2572 }
2573 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002574
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002575 if (win.mSurface == null || (win.getAttrs().flags
2576 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2577 || win.mSurfacePendingDestroy) {
2578 // We are being called from a local process, which
2579 // means outSurface holds its current surface. Ensure the
2580 // surface object is cleared, but we don't want it actually
2581 // destroyed at this point.
2582 win.mSurfacePendingDestroy = false;
2583 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002584 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002585 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002587 "Keeping surface, will report destroy: " + win);
2588 win.mReportDestroySurface = true;
2589 outSurface.copyFrom(win.mSurface);
2590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 }
2592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 if (focusMayChange) {
2594 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2595 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 imMayMove = false;
2597 }
2598 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2599 }
Romain Guy06882f82009-06-10 13:36:04 -07002600
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002601 // updateFocusedWindowLocked() already assigned layers so we only need to
2602 // reassign them at this point if the IM window state gets shuffled
2603 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002606 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2607 // Little hack here -- we -should- be able to rely on the
2608 // function to return true if the IME has moved and needs
2609 // its layer recomputed. However, if the IME was hidden
2610 // and isn't actually moved in the list, its layer may be
2611 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 assignLayers = true;
2613 }
2614 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002615 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002616 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002617 assignLayers = true;
2618 }
2619 }
Romain Guy06882f82009-06-10 13:36:04 -07002620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 mLayoutNeeded = true;
2622 win.mGivenInsetsPending = insetsPending;
2623 if (assignLayers) {
2624 assignLayersLocked();
2625 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002626 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002628 if (displayed && win.mIsWallpaper) {
2629 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002630 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002631 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 if (win.mAppToken != null) {
2633 win.mAppToken.updateReportedVisibilityLocked();
2634 }
2635 outFrame.set(win.mFrame);
2636 outContentInsets.set(win.mContentInsets);
2637 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002638 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002640 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641 + ", requestedHeight=" + requestedHeight
2642 + ", viewVisibility=" + viewVisibility
2643 + "\nRelayout returning frame=" + outFrame
2644 + ", surface=" + outSurface);
2645
Joe Onorato8a9b2202010-02-26 18:56:32 -08002646 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2648
2649 inTouchMode = mInTouchMode;
2650 }
2651
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002652 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 sendNewConfiguration();
2654 }
Romain Guy06882f82009-06-10 13:36:04 -07002655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2659 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2660 }
2661
2662 public void finishDrawingWindow(Session session, IWindow client) {
2663 final long origId = Binder.clearCallingIdentity();
2664 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002665 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002667 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2668 adjustWallpaperWindowsLocked();
2669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 mLayoutNeeded = true;
2671 performLayoutAndPlaceSurfacesLocked();
2672 }
2673 }
2674 Binder.restoreCallingIdentity(origId);
2675 }
2676
2677 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002678 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 + (lp != null ? lp.packageName : null)
2680 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2681 if (lp != null && lp.windowAnimations != 0) {
2682 // If this is a system resource, don't try to load it from the
2683 // application resources. It is nice to avoid loading application
2684 // resources if we can.
2685 String packageName = lp.packageName != null ? lp.packageName : "android";
2686 int resId = lp.windowAnimations;
2687 if ((resId&0xFF000000) == 0x01000000) {
2688 packageName = "android";
2689 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002690 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 + packageName);
2692 return AttributeCache.instance().get(packageName, resId,
2693 com.android.internal.R.styleable.WindowAnimation);
2694 }
2695 return null;
2696 }
Romain Guy06882f82009-06-10 13:36:04 -07002697
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002698 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002699 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002700 + packageName + " resId=0x" + Integer.toHexString(resId));
2701 if (packageName != null) {
2702 if ((resId&0xFF000000) == 0x01000000) {
2703 packageName = "android";
2704 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002705 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002706 + packageName);
2707 return AttributeCache.instance().get(packageName, resId,
2708 com.android.internal.R.styleable.WindowAnimation);
2709 }
2710 return null;
2711 }
2712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 private void applyEnterAnimationLocked(WindowState win) {
2714 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2715 if (win.mEnterAnimationPending) {
2716 win.mEnterAnimationPending = false;
2717 transit = WindowManagerPolicy.TRANSIT_ENTER;
2718 }
2719
2720 applyAnimationLocked(win, transit, true);
2721 }
2722
2723 private boolean applyAnimationLocked(WindowState win,
2724 int transit, boolean isEntrance) {
2725 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2726 // If we are trying to apply an animation, but already running
2727 // an animation of the same type, then just leave that one alone.
2728 return true;
2729 }
Romain Guy06882f82009-06-10 13:36:04 -07002730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 // Only apply an animation if the display isn't frozen. If it is
2732 // frozen, there is no reason to animate and it can cause strange
2733 // artifacts when we unfreeze the display if some different animation
2734 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002735 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 int anim = mPolicy.selectAnimationLw(win, transit);
2737 int attr = -1;
2738 Animation a = null;
2739 if (anim != 0) {
2740 a = AnimationUtils.loadAnimation(mContext, anim);
2741 } else {
2742 switch (transit) {
2743 case WindowManagerPolicy.TRANSIT_ENTER:
2744 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2745 break;
2746 case WindowManagerPolicy.TRANSIT_EXIT:
2747 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2748 break;
2749 case WindowManagerPolicy.TRANSIT_SHOW:
2750 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2751 break;
2752 case WindowManagerPolicy.TRANSIT_HIDE:
2753 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2754 break;
2755 }
2756 if (attr >= 0) {
2757 a = loadAnimation(win.mAttrs, attr);
2758 }
2759 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002760 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002761 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2762 + " mAnimation=" + win.mAnimation
2763 + " isEntrance=" + isEntrance);
2764 if (a != null) {
2765 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002766 RuntimeException e = null;
2767 if (!HIDE_STACK_CRAWLS) {
2768 e = new RuntimeException();
2769 e.fillInStackTrace();
2770 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002771 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773 win.setAnimation(a);
2774 win.mAnimationIsEntrance = isEntrance;
2775 }
2776 } else {
2777 win.clearAnimation();
2778 }
2779
2780 return win.mAnimation != null;
2781 }
2782
2783 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2784 int anim = 0;
2785 Context context = mContext;
2786 if (animAttr >= 0) {
2787 AttributeCache.Entry ent = getCachedAnimations(lp);
2788 if (ent != null) {
2789 context = ent.context;
2790 anim = ent.array.getResourceId(animAttr, 0);
2791 }
2792 }
2793 if (anim != 0) {
2794 return AnimationUtils.loadAnimation(context, anim);
2795 }
2796 return null;
2797 }
Romain Guy06882f82009-06-10 13:36:04 -07002798
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002799 private Animation loadAnimation(String packageName, int resId) {
2800 int anim = 0;
2801 Context context = mContext;
2802 if (resId >= 0) {
2803 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2804 if (ent != null) {
2805 context = ent.context;
2806 anim = resId;
2807 }
2808 }
2809 if (anim != 0) {
2810 return AnimationUtils.loadAnimation(context, anim);
2811 }
2812 return null;
2813 }
2814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 private boolean applyAnimationLocked(AppWindowToken wtoken,
2816 WindowManager.LayoutParams lp, int transit, boolean enter) {
2817 // Only apply an animation if the display isn't frozen. If it is
2818 // frozen, there is no reason to animate and it can cause strange
2819 // artifacts when we unfreeze the display if some different animation
2820 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002821 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002822 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002823 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002824 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002825 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002826 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002827 } else if (mNextAppTransitionPackage != null) {
2828 a = loadAnimation(mNextAppTransitionPackage, enter ?
2829 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002830 } else {
2831 int animAttr = 0;
2832 switch (transit) {
2833 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2834 animAttr = enter
2835 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2836 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2837 break;
2838 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2839 animAttr = enter
2840 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2841 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2842 break;
2843 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2844 animAttr = enter
2845 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2846 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2847 break;
2848 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2849 animAttr = enter
2850 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2851 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2852 break;
2853 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2854 animAttr = enter
2855 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2856 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2857 break;
2858 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2859 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002860 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002861 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2862 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002863 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002864 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002865 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2866 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002867 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002868 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002869 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002870 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2871 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2872 break;
2873 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2874 animAttr = enter
2875 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2876 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2877 break;
2878 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2879 animAttr = enter
2880 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2881 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002882 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002883 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002884 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002885 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002886 + " anim=" + a
2887 + " animAttr=0x" + Integer.toHexString(animAttr)
2888 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 if (a != null) {
2891 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002892 RuntimeException e = null;
2893 if (!HIDE_STACK_CRAWLS) {
2894 e = new RuntimeException();
2895 e.fillInStackTrace();
2896 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002897 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 }
2899 wtoken.setAnimation(a);
2900 }
2901 } else {
2902 wtoken.clearAnimation();
2903 }
2904
2905 return wtoken.animation != null;
2906 }
2907
2908 // -------------------------------------------------------------
2909 // Application Window Tokens
2910 // -------------------------------------------------------------
2911
2912 public void validateAppTokens(List tokens) {
2913 int v = tokens.size()-1;
2914 int m = mAppTokens.size()-1;
2915 while (v >= 0 && m >= 0) {
2916 AppWindowToken wtoken = mAppTokens.get(m);
2917 if (wtoken.removed) {
2918 m--;
2919 continue;
2920 }
2921 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002922 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2924 }
2925 v--;
2926 m--;
2927 }
2928 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002929 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 v--;
2931 }
2932 while (m >= 0) {
2933 AppWindowToken wtoken = mAppTokens.get(m);
2934 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002935 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937 m--;
2938 }
2939 }
2940
2941 boolean checkCallingPermission(String permission, String func) {
2942 // Quick check: if the calling permission is me, it's all okay.
2943 if (Binder.getCallingPid() == Process.myPid()) {
2944 return true;
2945 }
Romain Guy06882f82009-06-10 13:36:04 -07002946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 if (mContext.checkCallingPermission(permission)
2948 == PackageManager.PERMISSION_GRANTED) {
2949 return true;
2950 }
2951 String msg = "Permission Denial: " + func + " from pid="
2952 + Binder.getCallingPid()
2953 + ", uid=" + Binder.getCallingUid()
2954 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002955 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 return false;
2957 }
Romain Guy06882f82009-06-10 13:36:04 -07002958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 AppWindowToken findAppWindowToken(IBinder token) {
2960 WindowToken wtoken = mTokenMap.get(token);
2961 if (wtoken == null) {
2962 return null;
2963 }
2964 return wtoken.appWindowToken;
2965 }
Romain Guy06882f82009-06-10 13:36:04 -07002966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 public void addWindowToken(IBinder token, int type) {
2968 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2969 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002970 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 }
Romain Guy06882f82009-06-10 13:36:04 -07002972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 synchronized(mWindowMap) {
2974 WindowToken wtoken = mTokenMap.get(token);
2975 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002976 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002977 return;
2978 }
2979 wtoken = new WindowToken(token, type, true);
2980 mTokenMap.put(token, wtoken);
2981 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002982 if (type == TYPE_WALLPAPER) {
2983 mWallpaperTokens.add(wtoken);
2984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 }
2986 }
Romain Guy06882f82009-06-10 13:36:04 -07002987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 public void removeWindowToken(IBinder token) {
2989 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2990 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002991 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
2994 final long origId = Binder.clearCallingIdentity();
2995 synchronized(mWindowMap) {
2996 WindowToken wtoken = mTokenMap.remove(token);
2997 mTokenList.remove(wtoken);
2998 if (wtoken != null) {
2999 boolean delayed = false;
3000 if (!wtoken.hidden) {
3001 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003003 final int N = wtoken.windows.size();
3004 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003005
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 for (int i=0; i<N; i++) {
3007 WindowState win = wtoken.windows.get(i);
3008
3009 if (win.isAnimating()) {
3010 delayed = true;
3011 }
Romain Guy06882f82009-06-10 13:36:04 -07003012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013 if (win.isVisibleNow()) {
3014 applyAnimationLocked(win,
3015 WindowManagerPolicy.TRANSIT_EXIT, false);
3016 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3017 KeyWaiter.RETURN_NOTHING);
3018 changed = true;
3019 }
3020 }
3021
3022 if (changed) {
3023 mLayoutNeeded = true;
3024 performLayoutAndPlaceSurfacesLocked();
3025 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3026 }
Romain Guy06882f82009-06-10 13:36:04 -07003027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 if (delayed) {
3029 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003030 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3031 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 }
3033 }
Romain Guy06882f82009-06-10 13:36:04 -07003034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003036 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 }
3038 }
3039 Binder.restoreCallingIdentity(origId);
3040 }
3041
3042 public void addAppToken(int addPos, IApplicationToken token,
3043 int groupId, int requestedOrientation, boolean fullscreen) {
3044 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3045 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003046 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 }
Romain Guy06882f82009-06-10 13:36:04 -07003048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 synchronized(mWindowMap) {
3050 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3051 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003052 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 return;
3054 }
3055 wtoken = new AppWindowToken(token);
3056 wtoken.groupId = groupId;
3057 wtoken.appFullscreen = fullscreen;
3058 wtoken.requestedOrientation = requestedOrientation;
3059 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003060 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 mTokenMap.put(token.asBinder(), wtoken);
3062 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 // Application tokens start out hidden.
3065 wtoken.hidden = true;
3066 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 //dump();
3069 }
3070 }
Romain Guy06882f82009-06-10 13:36:04 -07003071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 public void setAppGroupId(IBinder token, int groupId) {
3073 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3074 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003075 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 }
3077
3078 synchronized(mWindowMap) {
3079 AppWindowToken wtoken = findAppWindowToken(token);
3080 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003081 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003082 return;
3083 }
3084 wtoken.groupId = groupId;
3085 }
3086 }
Romain Guy06882f82009-06-10 13:36:04 -07003087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 public int getOrientationFromWindowsLocked() {
3089 int pos = mWindows.size() - 1;
3090 while (pos >= 0) {
3091 WindowState wtoken = (WindowState) mWindows.get(pos);
3092 pos--;
3093 if (wtoken.mAppToken != null) {
3094 // We hit an application window. so the orientation will be determined by the
3095 // app window. No point in continuing further.
3096 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3097 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003098 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 continue;
3100 }
3101 int req = wtoken.mAttrs.screenOrientation;
3102 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3103 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3104 continue;
3105 } else {
3106 return req;
3107 }
3108 }
3109 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3110 }
Romain Guy06882f82009-06-10 13:36:04 -07003111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003113 int pos = mAppTokens.size() - 1;
3114 int curGroup = 0;
3115 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3116 boolean findingBehind = false;
3117 boolean haveGroup = false;
3118 boolean lastFullscreen = false;
3119 while (pos >= 0) {
3120 AppWindowToken wtoken = mAppTokens.get(pos);
3121 pos--;
3122 // if we're about to tear down this window and not seek for
3123 // the behind activity, don't use it for orientation
3124 if (!findingBehind
3125 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3126 continue;
3127 }
3128
3129 if (!haveGroup) {
3130 // We ignore any hidden applications on the top.
3131 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003132 continue;
3133 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003134 haveGroup = true;
3135 curGroup = wtoken.groupId;
3136 lastOrientation = wtoken.requestedOrientation;
3137 } else if (curGroup != wtoken.groupId) {
3138 // If we have hit a new application group, and the bottom
3139 // of the previous group didn't explicitly say to use
3140 // the orientation behind it, and the last app was
3141 // full screen, then we'll stick with the
3142 // user's orientation.
3143 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3144 && lastFullscreen) {
3145 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003148 int or = wtoken.requestedOrientation;
3149 // If this application is fullscreen, and didn't explicitly say
3150 // to use the orientation behind it, then just take whatever
3151 // orientation it has and ignores whatever is under it.
3152 lastFullscreen = wtoken.appFullscreen;
3153 if (lastFullscreen
3154 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3155 return or;
3156 }
3157 // If this application has requested an explicit orientation,
3158 // then use it.
3159 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3160 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3161 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3162 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3163 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3164 return or;
3165 }
3166 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3167 }
3168 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 }
Romain Guy06882f82009-06-10 13:36:04 -07003170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003172 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003173 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3174 "updateOrientationFromAppTokens()")) {
3175 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3176 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003177
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003178 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003180
3181 synchronized(mWindowMap) {
3182 if (updateOrientationFromAppTokensLocked()) {
3183 if (freezeThisOneIfNeeded != null) {
3184 AppWindowToken wtoken = findAppWindowToken(
3185 freezeThisOneIfNeeded);
3186 if (wtoken != null) {
3187 startAppFreezingScreenLocked(wtoken,
3188 ActivityInfo.CONFIG_ORIENTATION);
3189 }
3190 }
3191 config = computeNewConfigurationLocked();
3192
3193 } else if (currentConfig != null) {
3194 // No obvious action we need to take, but if our current
3195 // state mismatches the activity maanager's, update it
3196 mTempConfiguration.setToDefaults();
3197 if (computeNewConfigurationLocked(mTempConfiguration)) {
3198 if (currentConfig.diff(mTempConfiguration) != 0) {
3199 mWaitingForConfig = true;
3200 mLayoutNeeded = true;
3201 startFreezingDisplayLocked();
3202 config = new Configuration(mTempConfiguration);
3203 }
3204 }
3205 }
3206 }
3207
Dianne Hackborncfaef692009-06-15 14:24:44 -07003208 Binder.restoreCallingIdentity(ident);
3209 return config;
3210 }
3211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003213 * Determine the new desired orientation of the display, returning
3214 * a non-null new Configuration if it has changed from the current
3215 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3216 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3217 * SCREEN. This will typically be done for you if you call
3218 * sendNewConfiguration().
3219 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 * The orientation is computed from non-application windows first. If none of
3221 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003222 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003223 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3224 * android.os.IBinder)
3225 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003226 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003227 if (mDisplayFrozen) {
3228 // If the display is frozen, some activities may be in the middle
3229 // of restarting, and thus have removed their old window. If the
3230 // window has the flag to hide the lock screen, then the lock screen
3231 // can re-appear and inflict its own orientation on us. Keep the
3232 // orientation stable until this all settles down.
3233 return false;
3234 }
3235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 long ident = Binder.clearCallingIdentity();
3238 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003239 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003242 mForcedAppOrientation = req;
3243 //send a message to Policy indicating orientation change to take
3244 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003245 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003246 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3247 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3248 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 }
3250 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003251
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003252 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 } finally {
3254 Binder.restoreCallingIdentity(ident);
3255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 }
Romain Guy06882f82009-06-10 13:36:04 -07003257
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003258 int computeForcedAppOrientationLocked() {
3259 int req = getOrientationFromWindowsLocked();
3260 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3261 req = getOrientationFromAppTokensLocked();
3262 }
3263 return req;
3264 }
Romain Guy06882f82009-06-10 13:36:04 -07003265
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003266 public void setNewConfiguration(Configuration config) {
3267 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3268 "setNewConfiguration()")) {
3269 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3270 }
3271
3272 synchronized(mWindowMap) {
3273 mCurConfiguration = new Configuration(config);
3274 mWaitingForConfig = false;
3275 performLayoutAndPlaceSurfacesLocked();
3276 }
3277 }
3278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3280 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3281 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003282 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003283 }
Romain Guy06882f82009-06-10 13:36:04 -07003284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 synchronized(mWindowMap) {
3286 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3287 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003288 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 return;
3290 }
Romain Guy06882f82009-06-10 13:36:04 -07003291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 wtoken.requestedOrientation = requestedOrientation;
3293 }
3294 }
Romain Guy06882f82009-06-10 13:36:04 -07003295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 public int getAppOrientation(IApplicationToken token) {
3297 synchronized(mWindowMap) {
3298 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3299 if (wtoken == null) {
3300 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3301 }
Romain Guy06882f82009-06-10 13:36:04 -07003302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 return wtoken.requestedOrientation;
3304 }
3305 }
Romain Guy06882f82009-06-10 13:36:04 -07003306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3308 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3309 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003310 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 }
3312
3313 synchronized(mWindowMap) {
3314 boolean changed = false;
3315 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 changed = mFocusedApp != null;
3318 mFocusedApp = null;
3319 mKeyWaiter.tickle();
3320 } else {
3321 AppWindowToken newFocus = findAppWindowToken(token);
3322 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003323 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 return;
3325 }
3326 changed = mFocusedApp != newFocus;
3327 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003328 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 mKeyWaiter.tickle();
3330 }
3331
3332 if (moveFocusNow && changed) {
3333 final long origId = Binder.clearCallingIdentity();
3334 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3335 Binder.restoreCallingIdentity(origId);
3336 }
3337 }
3338 }
3339
3340 public void prepareAppTransition(int transit) {
3341 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3342 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003343 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 }
Romain Guy06882f82009-06-10 13:36:04 -07003345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003347 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 TAG, "Prepare app transition: transit=" + transit
3349 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003350 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003351 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3352 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003354 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3355 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3356 // Opening a new task always supersedes a close for the anim.
3357 mNextAppTransition = transit;
3358 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3359 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3360 // Opening a new activity always supersedes a close for the anim.
3361 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 }
3363 mAppTransitionReady = false;
3364 mAppTransitionTimeout = false;
3365 mStartingIconInTransition = false;
3366 mSkipAppTransitionAnimation = false;
3367 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3368 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3369 5000);
3370 }
3371 }
3372 }
3373
3374 public int getPendingAppTransition() {
3375 return mNextAppTransition;
3376 }
Romain Guy06882f82009-06-10 13:36:04 -07003377
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003378 public void overridePendingAppTransition(String packageName,
3379 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003380 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003381 mNextAppTransitionPackage = packageName;
3382 mNextAppTransitionEnter = enterAnim;
3383 mNextAppTransitionExit = exitAnim;
3384 }
3385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 public void executeAppTransition() {
3388 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3389 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003390 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003391 }
Romain Guy06882f82009-06-10 13:36:04 -07003392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003394 if (DEBUG_APP_TRANSITIONS) {
3395 RuntimeException e = new RuntimeException("here");
3396 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003397 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003398 + mNextAppTransition, e);
3399 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003400 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 mAppTransitionReady = true;
3402 final long origId = Binder.clearCallingIdentity();
3403 performLayoutAndPlaceSurfacesLocked();
3404 Binder.restoreCallingIdentity(origId);
3405 }
3406 }
3407 }
3408
3409 public void setAppStartingWindow(IBinder token, String pkg,
3410 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3411 IBinder transferFrom, boolean createIfNeeded) {
3412 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3413 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003414 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 }
3416
3417 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003418 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3420 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003422 AppWindowToken wtoken = findAppWindowToken(token);
3423 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003424 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425 return;
3426 }
3427
3428 // If the display is frozen, we won't do anything until the
3429 // actual window is displayed so there is no reason to put in
3430 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003431 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003432 return;
3433 }
Romain Guy06882f82009-06-10 13:36:04 -07003434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 if (wtoken.startingData != null) {
3436 return;
3437 }
Romain Guy06882f82009-06-10 13:36:04 -07003438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 if (transferFrom != null) {
3440 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3441 if (ttoken != null) {
3442 WindowState startingWindow = ttoken.startingWindow;
3443 if (startingWindow != null) {
3444 if (mStartingIconInTransition) {
3445 // In this case, the starting icon has already
3446 // been displayed, so start letting windows get
3447 // shown immediately without any more transitions.
3448 mSkipAppTransitionAnimation = true;
3449 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003450 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 "Moving existing starting from " + ttoken
3452 + " to " + wtoken);
3453 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 // Transfer the starting window over to the new
3456 // token.
3457 wtoken.startingData = ttoken.startingData;
3458 wtoken.startingView = ttoken.startingView;
3459 wtoken.startingWindow = startingWindow;
3460 ttoken.startingData = null;
3461 ttoken.startingView = null;
3462 ttoken.startingWindow = null;
3463 ttoken.startingMoved = true;
3464 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003465 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003467 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003468 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 mWindows.remove(startingWindow);
3470 ttoken.windows.remove(startingWindow);
3471 ttoken.allAppWindows.remove(startingWindow);
3472 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 // Propagate other interesting state between the
3475 // tokens. If the old token is displayed, we should
3476 // immediately force the new one to be displayed. If
3477 // it is animating, we need to move that animation to
3478 // the new one.
3479 if (ttoken.allDrawn) {
3480 wtoken.allDrawn = true;
3481 }
3482 if (ttoken.firstWindowDrawn) {
3483 wtoken.firstWindowDrawn = true;
3484 }
3485 if (!ttoken.hidden) {
3486 wtoken.hidden = false;
3487 wtoken.hiddenRequested = false;
3488 wtoken.willBeHidden = false;
3489 }
3490 if (wtoken.clientHidden != ttoken.clientHidden) {
3491 wtoken.clientHidden = ttoken.clientHidden;
3492 wtoken.sendAppVisibilityToClients();
3493 }
3494 if (ttoken.animation != null) {
3495 wtoken.animation = ttoken.animation;
3496 wtoken.animating = ttoken.animating;
3497 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3498 ttoken.animation = null;
3499 ttoken.animLayerAdjustment = 0;
3500 wtoken.updateLayers();
3501 ttoken.updateLayers();
3502 }
Romain Guy06882f82009-06-10 13:36:04 -07003503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 mLayoutNeeded = true;
3506 performLayoutAndPlaceSurfacesLocked();
3507 Binder.restoreCallingIdentity(origId);
3508 return;
3509 } else if (ttoken.startingData != null) {
3510 // The previous app was getting ready to show a
3511 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003512 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 "Moving pending starting from " + ttoken
3514 + " to " + wtoken);
3515 wtoken.startingData = ttoken.startingData;
3516 ttoken.startingData = null;
3517 ttoken.startingMoved = true;
3518 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3519 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3520 // want to process the message ASAP, before any other queued
3521 // messages.
3522 mH.sendMessageAtFrontOfQueue(m);
3523 return;
3524 }
3525 }
3526 }
3527
3528 // There is no existing starting window, and the caller doesn't
3529 // want us to create one, so that's it!
3530 if (!createIfNeeded) {
3531 return;
3532 }
Romain Guy06882f82009-06-10 13:36:04 -07003533
Dianne Hackborn284ac932009-08-28 10:34:25 -07003534 // If this is a translucent or wallpaper window, then don't
3535 // show a starting window -- the current effect (a full-screen
3536 // opaque starting window that fades away to the real contents
3537 // when it is ready) does not work for this.
3538 if (theme != 0) {
3539 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3540 com.android.internal.R.styleable.Window);
3541 if (ent.array.getBoolean(
3542 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3543 return;
3544 }
3545 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003546 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3547 return;
3548 }
3549 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003550 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3551 return;
3552 }
3553 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003555 mStartingIconInTransition = true;
3556 wtoken.startingData = new StartingData(
3557 pkg, theme, nonLocalizedLabel,
3558 labelRes, icon);
3559 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3560 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3561 // want to process the message ASAP, before any other queued
3562 // messages.
3563 mH.sendMessageAtFrontOfQueue(m);
3564 }
3565 }
3566
3567 public void setAppWillBeHidden(IBinder token) {
3568 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3569 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003570 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 }
3572
3573 AppWindowToken wtoken;
3574
3575 synchronized(mWindowMap) {
3576 wtoken = findAppWindowToken(token);
3577 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003578 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 -08003579 return;
3580 }
3581 wtoken.willBeHidden = true;
3582 }
3583 }
Romain Guy06882f82009-06-10 13:36:04 -07003584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3586 boolean visible, int transit, boolean performLayout) {
3587 boolean delayed = false;
3588
3589 if (wtoken.clientHidden == visible) {
3590 wtoken.clientHidden = !visible;
3591 wtoken.sendAppVisibilityToClients();
3592 }
Romain Guy06882f82009-06-10 13:36:04 -07003593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 wtoken.willBeHidden = false;
3595 if (wtoken.hidden == visible) {
3596 final int N = wtoken.allAppWindows.size();
3597 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003598 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3600 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003603
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003604 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 if (wtoken.animation == sDummyAnimation) {
3606 wtoken.animation = null;
3607 }
3608 applyAnimationLocked(wtoken, lp, transit, visible);
3609 changed = true;
3610 if (wtoken.animation != null) {
3611 delayed = runningAppAnimation = true;
3612 }
3613 }
Romain Guy06882f82009-06-10 13:36:04 -07003614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 for (int i=0; i<N; i++) {
3616 WindowState win = wtoken.allAppWindows.get(i);
3617 if (win == wtoken.startingWindow) {
3618 continue;
3619 }
3620
3621 if (win.isAnimating()) {
3622 delayed = true;
3623 }
Romain Guy06882f82009-06-10 13:36:04 -07003624
Joe Onorato8a9b2202010-02-26 18:56:32 -08003625 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 //win.dump(" ");
3627 if (visible) {
3628 if (!win.isVisibleNow()) {
3629 if (!runningAppAnimation) {
3630 applyAnimationLocked(win,
3631 WindowManagerPolicy.TRANSIT_ENTER, true);
3632 }
3633 changed = true;
3634 }
3635 } else if (win.isVisibleNow()) {
3636 if (!runningAppAnimation) {
3637 applyAnimationLocked(win,
3638 WindowManagerPolicy.TRANSIT_EXIT, false);
3639 }
3640 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3641 KeyWaiter.RETURN_NOTHING);
3642 changed = true;
3643 }
3644 }
3645
3646 wtoken.hidden = wtoken.hiddenRequested = !visible;
3647 if (!visible) {
3648 unsetAppFreezingScreenLocked(wtoken, true, true);
3649 } else {
3650 // If we are being set visible, and the starting window is
3651 // not yet displayed, then make sure it doesn't get displayed.
3652 WindowState swin = wtoken.startingWindow;
3653 if (swin != null && (swin.mDrawPending
3654 || swin.mCommitDrawPending)) {
3655 swin.mPolicyVisibility = false;
3656 swin.mPolicyVisibilityAfterAnim = false;
3657 }
3658 }
Romain Guy06882f82009-06-10 13:36:04 -07003659
Joe Onorato8a9b2202010-02-26 18:56:32 -08003660 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003661 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3662 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003663
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003664 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003666 if (performLayout) {
3667 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3668 performLayoutAndPlaceSurfacesLocked();
3669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 }
3671 }
3672
3673 if (wtoken.animation != null) {
3674 delayed = true;
3675 }
Romain Guy06882f82009-06-10 13:36:04 -07003676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 return delayed;
3678 }
3679
3680 public void setAppVisibility(IBinder token, boolean visible) {
3681 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3682 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003683 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685
3686 AppWindowToken wtoken;
3687
3688 synchronized(mWindowMap) {
3689 wtoken = findAppWindowToken(token);
3690 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 return;
3693 }
3694
3695 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003696 RuntimeException e = null;
3697 if (!HIDE_STACK_CRAWLS) {
3698 e = new RuntimeException();
3699 e.fillInStackTrace();
3700 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003701 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 + "): mNextAppTransition=" + mNextAppTransition
3703 + " hidden=" + wtoken.hidden
3704 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3705 }
Romain Guy06882f82009-06-10 13:36:04 -07003706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 // If we are preparing an app transition, then delay changing
3708 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003709 if (!mDisplayFrozen && mPolicy.isScreenOn()
3710 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 // Already in requested state, don't do anything more.
3712 if (wtoken.hiddenRequested != visible) {
3713 return;
3714 }
3715 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003716
Joe Onorato8a9b2202010-02-26 18:56:32 -08003717 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 TAG, "Setting dummy animation on: " + wtoken);
3719 wtoken.setDummyAnimation();
3720 mOpeningApps.remove(wtoken);
3721 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003722 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 wtoken.inPendingTransaction = true;
3724 if (visible) {
3725 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 wtoken.startingDisplayed = false;
3727 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003728
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003729 // If the token is currently hidden (should be the
3730 // common case), then we need to set up to wait for
3731 // its windows to be ready.
3732 if (wtoken.hidden) {
3733 wtoken.allDrawn = false;
3734 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003735
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003736 if (wtoken.clientHidden) {
3737 // In the case where we are making an app visible
3738 // but holding off for a transition, we still need
3739 // to tell the client to make its windows visible so
3740 // they get drawn. Otherwise, we will wait on
3741 // performing the transition until all windows have
3742 // been drawn, they never will be, and we are sad.
3743 wtoken.clientHidden = false;
3744 wtoken.sendAppVisibilityToClients();
3745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
3747 } else {
3748 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003749
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003750 // If the token is currently visible (should be the
3751 // common case), then set up to wait for it to be hidden.
3752 if (!wtoken.hidden) {
3753 wtoken.waitingToHide = true;
3754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 }
3756 return;
3757 }
Romain Guy06882f82009-06-10 13:36:04 -07003758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003759 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003760 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 wtoken.updateReportedVisibilityLocked();
3762 Binder.restoreCallingIdentity(origId);
3763 }
3764 }
3765
3766 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3767 boolean unfreezeSurfaceNow, boolean force) {
3768 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003769 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 + " force=" + force);
3771 final int N = wtoken.allAppWindows.size();
3772 boolean unfrozeWindows = false;
3773 for (int i=0; i<N; i++) {
3774 WindowState w = wtoken.allAppWindows.get(i);
3775 if (w.mAppFreezing) {
3776 w.mAppFreezing = false;
3777 if (w.mSurface != null && !w.mOrientationChanging) {
3778 w.mOrientationChanging = true;
3779 }
3780 unfrozeWindows = true;
3781 }
3782 }
3783 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003784 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 wtoken.freezingScreen = false;
3786 mAppsFreezingScreen--;
3787 }
3788 if (unfreezeSurfaceNow) {
3789 if (unfrozeWindows) {
3790 mLayoutNeeded = true;
3791 performLayoutAndPlaceSurfacesLocked();
3792 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003793 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
3795 }
3796 }
Romain Guy06882f82009-06-10 13:36:04 -07003797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3799 int configChanges) {
3800 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003801 RuntimeException e = null;
3802 if (!HIDE_STACK_CRAWLS) {
3803 e = new RuntimeException();
3804 e.fillInStackTrace();
3805 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003806 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 + ": hidden=" + wtoken.hidden + " freezing="
3808 + wtoken.freezingScreen, e);
3809 }
3810 if (!wtoken.hiddenRequested) {
3811 if (!wtoken.freezingScreen) {
3812 wtoken.freezingScreen = true;
3813 mAppsFreezingScreen++;
3814 if (mAppsFreezingScreen == 1) {
3815 startFreezingDisplayLocked();
3816 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3817 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3818 5000);
3819 }
3820 }
3821 final int N = wtoken.allAppWindows.size();
3822 for (int i=0; i<N; i++) {
3823 WindowState w = wtoken.allAppWindows.get(i);
3824 w.mAppFreezing = true;
3825 }
3826 }
3827 }
Romain Guy06882f82009-06-10 13:36:04 -07003828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 public void startAppFreezingScreen(IBinder token, int configChanges) {
3830 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3831 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003832 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 }
3834
3835 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003836 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003837 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 return;
3839 }
Romain Guy06882f82009-06-10 13:36:04 -07003840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 AppWindowToken wtoken = findAppWindowToken(token);
3842 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003843 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 return;
3845 }
3846 final long origId = Binder.clearCallingIdentity();
3847 startAppFreezingScreenLocked(wtoken, configChanges);
3848 Binder.restoreCallingIdentity(origId);
3849 }
3850 }
Romain Guy06882f82009-06-10 13:36:04 -07003851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 public void stopAppFreezingScreen(IBinder token, boolean force) {
3853 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3854 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003855 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003856 }
3857
3858 synchronized(mWindowMap) {
3859 AppWindowToken wtoken = findAppWindowToken(token);
3860 if (wtoken == null || wtoken.appToken == null) {
3861 return;
3862 }
3863 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003864 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3866 unsetAppFreezingScreenLocked(wtoken, true, force);
3867 Binder.restoreCallingIdentity(origId);
3868 }
3869 }
Romain Guy06882f82009-06-10 13:36:04 -07003870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003871 public void removeAppToken(IBinder token) {
3872 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3873 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003874 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 }
3876
3877 AppWindowToken wtoken = null;
3878 AppWindowToken startingToken = null;
3879 boolean delayed = false;
3880
3881 final long origId = Binder.clearCallingIdentity();
3882 synchronized(mWindowMap) {
3883 WindowToken basewtoken = mTokenMap.remove(token);
3884 mTokenList.remove(basewtoken);
3885 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003886 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003887 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 wtoken.inPendingTransaction = false;
3889 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003890 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003891 if (mClosingApps.contains(wtoken)) {
3892 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003893 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003895 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 delayed = true;
3897 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003898 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 TAG, "Removing app " + wtoken + " delayed=" + delayed
3900 + " animation=" + wtoken.animation
3901 + " animating=" + wtoken.animating);
3902 if (delayed) {
3903 // set the token aside because it has an active animation to be finished
3904 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003905 } else {
3906 // Make sure there is no animation running on this token,
3907 // so any windows associated with it will be removed as
3908 // soon as their animations are complete
3909 wtoken.animation = null;
3910 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 }
3912 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003913 if (mLastEnterAnimToken == wtoken) {
3914 mLastEnterAnimToken = null;
3915 mLastEnterAnimParams = null;
3916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 wtoken.removed = true;
3918 if (wtoken.startingData != null) {
3919 startingToken = wtoken;
3920 }
3921 unsetAppFreezingScreenLocked(wtoken, true, true);
3922 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003923 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 mFocusedApp = null;
3925 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3926 mKeyWaiter.tickle();
3927 }
3928 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003929 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 }
Romain Guy06882f82009-06-10 13:36:04 -07003931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 if (!delayed && wtoken != null) {
3933 wtoken.updateReportedVisibilityLocked();
3934 }
3935 }
3936 Binder.restoreCallingIdentity(origId);
3937
3938 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003939 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 + startingToken + ": app token removed");
3941 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3942 mH.sendMessage(m);
3943 }
3944 }
3945
3946 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3947 final int NW = token.windows.size();
3948 for (int i=0; i<NW; i++) {
3949 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003950 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 mWindows.remove(win);
3952 int j = win.mChildWindows.size();
3953 while (j > 0) {
3954 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003955 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003956 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003957 "Tmp removing child window " + cwin);
3958 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 }
3960 }
3961 return NW > 0;
3962 }
3963
3964 void dumpAppTokensLocked() {
3965 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003966 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 }
3968 }
Romain Guy06882f82009-06-10 13:36:04 -07003969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 void dumpWindowsLocked() {
3971 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003972 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 }
3974 }
Romain Guy06882f82009-06-10 13:36:04 -07003975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 private int findWindowOffsetLocked(int tokenPos) {
3977 final int NW = mWindows.size();
3978
3979 if (tokenPos >= mAppTokens.size()) {
3980 int i = NW;
3981 while (i > 0) {
3982 i--;
3983 WindowState win = (WindowState)mWindows.get(i);
3984 if (win.getAppToken() != null) {
3985 return i+1;
3986 }
3987 }
3988 }
3989
3990 while (tokenPos > 0) {
3991 // Find the first app token below the new position that has
3992 // a window displayed.
3993 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003994 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003996 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003997 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07003998 "Skipping token -- currently sending to bottom");
3999 tokenPos--;
4000 continue;
4001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 int i = wtoken.windows.size();
4003 while (i > 0) {
4004 i--;
4005 WindowState win = wtoken.windows.get(i);
4006 int j = win.mChildWindows.size();
4007 while (j > 0) {
4008 j--;
4009 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004010 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 for (int pos=NW-1; pos>=0; pos--) {
4012 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004013 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004014 "Found child win @" + (pos+1));
4015 return pos+1;
4016 }
4017 }
4018 }
4019 }
4020 for (int pos=NW-1; pos>=0; pos--) {
4021 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004022 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 return pos+1;
4024 }
4025 }
4026 }
4027 tokenPos--;
4028 }
4029
4030 return 0;
4031 }
4032
4033 private final int reAddWindowLocked(int index, WindowState win) {
4034 final int NCW = win.mChildWindows.size();
4035 boolean added = false;
4036 for (int j=0; j<NCW; j++) {
4037 WindowState cwin = (WindowState)win.mChildWindows.get(j);
4038 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004039 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004040 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 mWindows.add(index, win);
4042 index++;
4043 added = true;
4044 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004045 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004046 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 mWindows.add(index, cwin);
4048 index++;
4049 }
4050 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004051 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004052 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 mWindows.add(index, win);
4054 index++;
4055 }
4056 return index;
4057 }
Romain Guy06882f82009-06-10 13:36:04 -07004058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4060 final int NW = token.windows.size();
4061 for (int i=0; i<NW; i++) {
4062 index = reAddWindowLocked(index, token.windows.get(i));
4063 }
4064 return index;
4065 }
4066
4067 public void moveAppToken(int index, IBinder token) {
4068 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4069 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004070 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 }
4072
4073 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004074 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 if (DEBUG_REORDER) dumpAppTokensLocked();
4076 final AppWindowToken wtoken = findAppWindowToken(token);
4077 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004078 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 + token + " (" + wtoken + ")");
4080 return;
4081 }
4082 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004083 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004087 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 if (DEBUG_REORDER) dumpWindowsLocked();
4089 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 if (DEBUG_REORDER) dumpWindowsLocked();
4092 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004093 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 if (DEBUG_REORDER) dumpWindowsLocked();
4095 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 mLayoutNeeded = true;
4097 performLayoutAndPlaceSurfacesLocked();
4098 }
4099 Binder.restoreCallingIdentity(origId);
4100 }
4101 }
4102
4103 private void removeAppTokensLocked(List<IBinder> tokens) {
4104 // XXX This should be done more efficiently!
4105 // (take advantage of the fact that both lists should be
4106 // ordered in the same way.)
4107 int N = tokens.size();
4108 for (int i=0; i<N; i++) {
4109 IBinder token = tokens.get(i);
4110 final AppWindowToken wtoken = findAppWindowToken(token);
4111 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004112 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004113 + token + " (" + wtoken + ")");
4114 i--;
4115 N--;
4116 }
4117 }
4118 }
4119
Dianne Hackborna8f60182009-09-01 19:01:50 -07004120 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4121 boolean updateFocusAndLayout) {
4122 // First remove all of the windows from the list.
4123 tmpRemoveAppWindowsLocked(wtoken);
4124
4125 // Where to start adding?
4126 int pos = findWindowOffsetLocked(tokenPos);
4127
4128 // And now add them back at the correct place.
4129 pos = reAddAppWindowsLocked(pos, wtoken);
4130
4131 if (updateFocusAndLayout) {
4132 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4133 assignLayersLocked();
4134 }
4135 mLayoutNeeded = true;
4136 performLayoutAndPlaceSurfacesLocked();
4137 }
4138 }
4139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4141 // First remove all of the windows from the list.
4142 final int N = tokens.size();
4143 int i;
4144 for (i=0; i<N; i++) {
4145 WindowToken token = mTokenMap.get(tokens.get(i));
4146 if (token != null) {
4147 tmpRemoveAppWindowsLocked(token);
4148 }
4149 }
4150
4151 // Where to start adding?
4152 int pos = findWindowOffsetLocked(tokenPos);
4153
4154 // And now add them back at the correct place.
4155 for (i=0; i<N; i++) {
4156 WindowToken token = mTokenMap.get(tokens.get(i));
4157 if (token != null) {
4158 pos = reAddAppWindowsLocked(pos, token);
4159 }
4160 }
4161
Dianne Hackborna8f60182009-09-01 19:01:50 -07004162 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4163 assignLayersLocked();
4164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 mLayoutNeeded = true;
4166 performLayoutAndPlaceSurfacesLocked();
4167
4168 //dump();
4169 }
4170
4171 public void moveAppTokensToTop(List<IBinder> tokens) {
4172 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4173 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004174 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004175 }
4176
4177 final long origId = Binder.clearCallingIdentity();
4178 synchronized(mWindowMap) {
4179 removeAppTokensLocked(tokens);
4180 final int N = tokens.size();
4181 for (int i=0; i<N; i++) {
4182 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4183 if (wt != null) {
4184 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004185 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004186 mToTopApps.remove(wt);
4187 mToBottomApps.remove(wt);
4188 mToTopApps.add(wt);
4189 wt.sendingToBottom = false;
4190 wt.sendingToTop = true;
4191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 }
4193 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004194
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004195 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004196 moveAppWindowsLocked(tokens, mAppTokens.size());
4197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 }
4199 Binder.restoreCallingIdentity(origId);
4200 }
4201
4202 public void moveAppTokensToBottom(List<IBinder> tokens) {
4203 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4204 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004205 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 }
4207
4208 final long origId = Binder.clearCallingIdentity();
4209 synchronized(mWindowMap) {
4210 removeAppTokensLocked(tokens);
4211 final int N = tokens.size();
4212 int pos = 0;
4213 for (int i=0; i<N; i++) {
4214 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4215 if (wt != null) {
4216 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004217 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004218 mToTopApps.remove(wt);
4219 mToBottomApps.remove(wt);
4220 mToBottomApps.add(i, wt);
4221 wt.sendingToTop = false;
4222 wt.sendingToBottom = true;
4223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 pos++;
4225 }
4226 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004227
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004228 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004229 moveAppWindowsLocked(tokens, 0);
4230 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 }
4232 Binder.restoreCallingIdentity(origId);
4233 }
4234
4235 // -------------------------------------------------------------
4236 // Misc IWindowSession methods
4237 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004238
Jim Miller284b62e2010-06-08 14:27:42 -07004239 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004240 {
Jim Miller284b62e2010-06-08 14:27:42 -07004241 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4242 // called before DevicePolicyManagerService has started.
4243 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4244 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4245 Context.DEVICE_POLICY_SERVICE);
4246 if (dpm != null) {
4247 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4248 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4249 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4250 }
Jim Millerd6b57052010-06-07 17:52:42 -07004251 }
Jim Miller284b62e2010-06-08 14:27:42 -07004252 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004253 }
4254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004256 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 != PackageManager.PERMISSION_GRANTED) {
4258 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4259 }
Jim Millerd6b57052010-06-07 17:52:42 -07004260
Jim Miller284b62e2010-06-08 14:27:42 -07004261 synchronized (mKeyguardTokenWatcher) {
4262 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 }
4265
4266 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004267 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 != PackageManager.PERMISSION_GRANTED) {
4269 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004271
Jim Miller284b62e2010-06-08 14:27:42 -07004272 synchronized (mKeyguardTokenWatcher) {
4273 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004274
Jim Miller284b62e2010-06-08 14:27:42 -07004275 if (!mKeyguardTokenWatcher.isAcquired()) {
4276 // If we are the last one to reenable the keyguard wait until
4277 // we have actually finished reenabling until returning.
4278 // It is possible that reenableKeyguard() can be called before
4279 // the previous disableKeyguard() is handled, in which case
4280 // neither mKeyguardTokenWatcher.acquired() or released() would
4281 // be called. In that case mKeyguardDisabled will be false here
4282 // and we have nothing to wait for.
4283 while (mKeyguardDisabled) {
4284 try {
4285 mKeyguardTokenWatcher.wait();
4286 } catch (InterruptedException e) {
4287 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 }
4289 }
4290 }
4291 }
4292 }
4293
4294 /**
4295 * @see android.app.KeyguardManager#exitKeyguardSecurely
4296 */
4297 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004298 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 != PackageManager.PERMISSION_GRANTED) {
4300 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4301 }
4302 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4303 public void onKeyguardExitResult(boolean success) {
4304 try {
4305 callback.onKeyguardExitResult(success);
4306 } catch (RemoteException e) {
4307 // Client has died, we don't care.
4308 }
4309 }
4310 });
4311 }
4312
4313 public boolean inKeyguardRestrictedInputMode() {
4314 return mPolicy.inKeyguardRestrictedKeyInputMode();
4315 }
Romain Guy06882f82009-06-10 13:36:04 -07004316
Dianne Hackbornffa42482009-09-23 22:20:11 -07004317 public void closeSystemDialogs(String reason) {
4318 synchronized(mWindowMap) {
4319 for (int i=mWindows.size()-1; i>=0; i--) {
4320 WindowState w = (WindowState)mWindows.get(i);
4321 if (w.mSurface != null) {
4322 try {
4323 w.mClient.closeSystemDialogs(reason);
4324 } catch (RemoteException e) {
4325 }
4326 }
4327 }
4328 }
4329 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 static float fixScale(float scale) {
4332 if (scale < 0) scale = 0;
4333 else if (scale > 20) scale = 20;
4334 return Math.abs(scale);
4335 }
Romain Guy06882f82009-06-10 13:36:04 -07004336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 public void setAnimationScale(int which, float scale) {
4338 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4339 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004340 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 }
4342
4343 if (scale < 0) scale = 0;
4344 else if (scale > 20) scale = 20;
4345 scale = Math.abs(scale);
4346 switch (which) {
4347 case 0: mWindowAnimationScale = fixScale(scale); break;
4348 case 1: mTransitionAnimationScale = fixScale(scale); break;
4349 }
Romain Guy06882f82009-06-10 13:36:04 -07004350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 // Persist setting
4352 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4353 }
Romain Guy06882f82009-06-10 13:36:04 -07004354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 public void setAnimationScales(float[] scales) {
4356 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4357 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004358 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 }
4360
4361 if (scales != null) {
4362 if (scales.length >= 1) {
4363 mWindowAnimationScale = fixScale(scales[0]);
4364 }
4365 if (scales.length >= 2) {
4366 mTransitionAnimationScale = fixScale(scales[1]);
4367 }
4368 }
Romain Guy06882f82009-06-10 13:36:04 -07004369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004370 // Persist setting
4371 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4372 }
Romain Guy06882f82009-06-10 13:36:04 -07004373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 public float getAnimationScale(int which) {
4375 switch (which) {
4376 case 0: return mWindowAnimationScale;
4377 case 1: return mTransitionAnimationScale;
4378 }
4379 return 0;
4380 }
Romain Guy06882f82009-06-10 13:36:04 -07004381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 public float[] getAnimationScales() {
4383 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4384 }
Romain Guy06882f82009-06-10 13:36:04 -07004385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 public int getSwitchState(int sw) {
4387 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4388 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004389 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004391 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4392 return mInputManager.getSwitchState(sw);
4393 } else {
4394 return KeyInputQueue.getSwitchState(sw);
4395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 }
Romain Guy06882f82009-06-10 13:36:04 -07004397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 public int getSwitchStateForDevice(int devid, int sw) {
4399 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4400 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004401 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004403 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4404 return mInputManager.getSwitchState(devid, sw);
4405 } else {
4406 return KeyInputQueue.getSwitchState(devid, sw);
4407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 }
Romain Guy06882f82009-06-10 13:36:04 -07004409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 public int getScancodeState(int sw) {
4411 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4412 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004413 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004415 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4416 return mInputManager.getScancodeState(sw);
4417 } else {
4418 return mQueue.getScancodeState(sw);
4419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 }
Romain Guy06882f82009-06-10 13:36:04 -07004421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 public int getScancodeStateForDevice(int devid, int sw) {
4423 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4424 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004425 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004427 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4428 return mInputManager.getScancodeState(devid, sw);
4429 } else {
4430 return mQueue.getScancodeState(devid, sw);
4431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004432 }
Romain Guy06882f82009-06-10 13:36:04 -07004433
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004434 public int getTrackballScancodeState(int sw) {
4435 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4436 "getTrackballScancodeState()")) {
4437 throw new SecurityException("Requires READ_INPUT_STATE permission");
4438 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004439 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4440 return mInputManager.getTrackballScancodeState(sw);
4441 } else {
4442 return mQueue.getTrackballScancodeState(sw);
4443 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004444 }
4445
4446 public int getDPadScancodeState(int sw) {
4447 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4448 "getDPadScancodeState()")) {
4449 throw new SecurityException("Requires READ_INPUT_STATE permission");
4450 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004451 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4452 return mInputManager.getDPadScancodeState(sw);
4453 } else {
4454 return mQueue.getDPadScancodeState(sw);
4455 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004456 }
4457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 public int getKeycodeState(int sw) {
4459 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4460 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004461 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004463 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4464 return mInputManager.getKeycodeState(sw);
4465 } else {
4466 return mQueue.getKeycodeState(sw);
4467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 }
Romain Guy06882f82009-06-10 13:36:04 -07004469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 public int getKeycodeStateForDevice(int devid, int sw) {
4471 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4472 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004473 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004475 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4476 return mInputManager.getKeycodeState(devid, sw);
4477 } else {
4478 return mQueue.getKeycodeState(devid, sw);
4479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004480 }
Romain Guy06882f82009-06-10 13:36:04 -07004481
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004482 public int getTrackballKeycodeState(int sw) {
4483 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4484 "getTrackballKeycodeState()")) {
4485 throw new SecurityException("Requires READ_INPUT_STATE permission");
4486 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004487 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4488 return mInputManager.getTrackballKeycodeState(sw);
4489 } else {
4490 return mQueue.getTrackballKeycodeState(sw);
4491 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004492 }
4493
4494 public int getDPadKeycodeState(int sw) {
4495 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4496 "getDPadKeycodeState()")) {
4497 throw new SecurityException("Requires READ_INPUT_STATE permission");
4498 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004499 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4500 return mInputManager.getDPadKeycodeState(sw);
4501 } else {
4502 return mQueue.getDPadKeycodeState(sw);
4503 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004504 }
4505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004507 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4508 return mInputManager.hasKeys(keycodes, keyExists);
4509 } else {
4510 return KeyInputQueue.hasKeys(keycodes, keyExists);
4511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 }
Romain Guy06882f82009-06-10 13:36:04 -07004513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 public void enableScreenAfterBoot() {
4515 synchronized(mWindowMap) {
4516 if (mSystemBooted) {
4517 return;
4518 }
4519 mSystemBooted = true;
4520 }
Romain Guy06882f82009-06-10 13:36:04 -07004521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522 performEnableScreen();
4523 }
Romain Guy06882f82009-06-10 13:36:04 -07004524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 public void enableScreenIfNeededLocked() {
4526 if (mDisplayEnabled) {
4527 return;
4528 }
4529 if (!mSystemBooted) {
4530 return;
4531 }
4532 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4533 }
Romain Guy06882f82009-06-10 13:36:04 -07004534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 public void performEnableScreen() {
4536 synchronized(mWindowMap) {
4537 if (mDisplayEnabled) {
4538 return;
4539 }
4540 if (!mSystemBooted) {
4541 return;
4542 }
Romain Guy06882f82009-06-10 13:36:04 -07004543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544 // Don't enable the screen until all existing windows
4545 // have been drawn.
4546 final int N = mWindows.size();
4547 for (int i=0; i<N; i++) {
4548 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004549 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 return;
4551 }
4552 }
Romain Guy06882f82009-06-10 13:36:04 -07004553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 mDisplayEnabled = true;
4555 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004556 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 StringWriter sw = new StringWriter();
4558 PrintWriter pw = new PrintWriter(sw);
4559 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004560 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 }
4562 try {
4563 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4564 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004565 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 Parcel data = Parcel.obtain();
4567 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4568 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4569 data, null, 0);
4570 data.recycle();
4571 }
4572 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004573 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 }
4575 }
Romain Guy06882f82009-06-10 13:36:04 -07004576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004580 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4581 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 }
Romain Guy06882f82009-06-10 13:36:04 -07004583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 public void setInTouchMode(boolean mode) {
4585 synchronized(mWindowMap) {
4586 mInTouchMode = mode;
4587 }
4588 }
4589
Romain Guy06882f82009-06-10 13:36:04 -07004590 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004591 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004593 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004594 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 }
4596
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004597 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 }
Romain Guy06882f82009-06-10 13:36:04 -07004599
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004600 public void setRotationUnchecked(int rotation,
4601 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004602 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 long origId = Binder.clearCallingIdentity();
4606 boolean changed;
4607 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004608 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
Romain Guy06882f82009-06-10 13:36:04 -07004610
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004611 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 sendNewConfiguration();
4613 }
Romain Guy06882f82009-06-10 13:36:04 -07004614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 Binder.restoreCallingIdentity(origId);
4616 }
Romain Guy06882f82009-06-10 13:36:04 -07004617
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004618 /**
4619 * Apply a new rotation to the screen, respecting the requests of
4620 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4621 * re-evaluate the desired rotation.
4622 *
4623 * Returns null if the rotation has been changed. In this case YOU
4624 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4625 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004626 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 boolean changed;
4628 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4629 rotation = mRequestedRotation;
4630 } else {
4631 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004632 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004634 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004635 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004637 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004641 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 "Rotation changed to " + rotation
4643 + " from " + mRotation
4644 + " (forceApp=" + mForcedAppOrientation
4645 + ", req=" + mRequestedRotation + ")");
4646 mRotation = rotation;
4647 mWindowsFreezingScreen = true;
4648 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4649 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4650 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004651 mWaitingForConfig = true;
4652 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004654 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004655 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4656 mInputManager.setDisplayOrientation(0, rotation);
4657 } else {
4658 mQueue.setOrientation(rotation);
4659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004661 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 }
4663 for (int i=mWindows.size()-1; i>=0; i--) {
4664 WindowState w = (WindowState)mWindows.get(i);
4665 if (w.mSurface != null) {
4666 w.mOrientationChanging = true;
4667 }
4668 }
4669 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4670 try {
4671 mRotationWatchers.get(i).onRotationChanged(rotation);
4672 } catch (RemoteException e) {
4673 }
4674 }
4675 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 return changed;
4678 }
Romain Guy06882f82009-06-10 13:36:04 -07004679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 public int getRotation() {
4681 return mRotation;
4682 }
4683
4684 public int watchRotation(IRotationWatcher watcher) {
4685 final IBinder watcherBinder = watcher.asBinder();
4686 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4687 public void binderDied() {
4688 synchronized (mWindowMap) {
4689 for (int i=0; i<mRotationWatchers.size(); i++) {
4690 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004691 IRotationWatcher removed = mRotationWatchers.remove(i);
4692 if (removed != null) {
4693 removed.asBinder().unlinkToDeath(this, 0);
4694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 i--;
4696 }
4697 }
4698 }
4699 }
4700 };
Romain Guy06882f82009-06-10 13:36:04 -07004701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004702 synchronized (mWindowMap) {
4703 try {
4704 watcher.asBinder().linkToDeath(dr, 0);
4705 mRotationWatchers.add(watcher);
4706 } catch (RemoteException e) {
4707 // Client died, no cleanup needed.
4708 }
Romain Guy06882f82009-06-10 13:36:04 -07004709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 return mRotation;
4711 }
4712 }
4713
4714 /**
4715 * Starts the view server on the specified port.
4716 *
4717 * @param port The port to listener to.
4718 *
4719 * @return True if the server was successfully started, false otherwise.
4720 *
4721 * @see com.android.server.ViewServer
4722 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4723 */
4724 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004725 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 return false;
4727 }
4728
4729 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4730 return false;
4731 }
4732
4733 if (port < 1024) {
4734 return false;
4735 }
4736
4737 if (mViewServer != null) {
4738 if (!mViewServer.isRunning()) {
4739 try {
4740 return mViewServer.start();
4741 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004742 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 }
4744 }
4745 return false;
4746 }
4747
4748 try {
4749 mViewServer = new ViewServer(this, port);
4750 return mViewServer.start();
4751 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004752 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 }
4754 return false;
4755 }
4756
Romain Guy06882f82009-06-10 13:36:04 -07004757 private boolean isSystemSecure() {
4758 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4759 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4760 }
4761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 /**
4763 * Stops the view server if it exists.
4764 *
4765 * @return True if the server stopped, false if it wasn't started or
4766 * couldn't be stopped.
4767 *
4768 * @see com.android.server.ViewServer
4769 */
4770 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004771 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004772 return false;
4773 }
4774
4775 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4776 return false;
4777 }
4778
4779 if (mViewServer != null) {
4780 return mViewServer.stop();
4781 }
4782 return false;
4783 }
4784
4785 /**
4786 * Indicates whether the view server is running.
4787 *
4788 * @return True if the server is running, false otherwise.
4789 *
4790 * @see com.android.server.ViewServer
4791 */
4792 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004793 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 return false;
4795 }
4796
4797 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4798 return false;
4799 }
4800
4801 return mViewServer != null && mViewServer.isRunning();
4802 }
4803
4804 /**
4805 * Lists all availble windows in the system. The listing is written in the
4806 * specified Socket's output stream with the following syntax:
4807 * windowHashCodeInHexadecimal windowName
4808 * Each line of the ouput represents a different window.
4809 *
4810 * @param client The remote client to send the listing to.
4811 * @return False if an error occured, true otherwise.
4812 */
4813 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004814 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004815 return false;
4816 }
4817
4818 boolean result = true;
4819
4820 Object[] windows;
4821 synchronized (mWindowMap) {
4822 windows = new Object[mWindows.size()];
4823 //noinspection unchecked
4824 windows = mWindows.toArray(windows);
4825 }
4826
4827 BufferedWriter out = null;
4828
4829 // Any uncaught exception will crash the system process
4830 try {
4831 OutputStream clientStream = client.getOutputStream();
4832 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4833
4834 final int count = windows.length;
4835 for (int i = 0; i < count; i++) {
4836 final WindowState w = (WindowState) windows[i];
4837 out.write(Integer.toHexString(System.identityHashCode(w)));
4838 out.write(' ');
4839 out.append(w.mAttrs.getTitle());
4840 out.write('\n');
4841 }
4842
4843 out.write("DONE.\n");
4844 out.flush();
4845 } catch (Exception e) {
4846 result = false;
4847 } finally {
4848 if (out != null) {
4849 try {
4850 out.close();
4851 } catch (IOException e) {
4852 result = false;
4853 }
4854 }
4855 }
4856
4857 return result;
4858 }
4859
4860 /**
4861 * Sends a command to a target window. The result of the command, if any, will be
4862 * written in the output stream of the specified socket.
4863 *
4864 * The parameters must follow this syntax:
4865 * windowHashcode extra
4866 *
4867 * Where XX is the length in characeters of the windowTitle.
4868 *
4869 * The first parameter is the target window. The window with the specified hashcode
4870 * will be the target. If no target can be found, nothing happens. The extra parameters
4871 * will be delivered to the target window and as parameters to the command itself.
4872 *
4873 * @param client The remote client to sent the result, if any, to.
4874 * @param command The command to execute.
4875 * @param parameters The command parameters.
4876 *
4877 * @return True if the command was successfully delivered, false otherwise. This does
4878 * not indicate whether the command itself was successful.
4879 */
4880 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004881 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 return false;
4883 }
4884
4885 boolean success = true;
4886 Parcel data = null;
4887 Parcel reply = null;
4888
4889 // Any uncaught exception will crash the system process
4890 try {
4891 // Find the hashcode of the window
4892 int index = parameters.indexOf(' ');
4893 if (index == -1) {
4894 index = parameters.length();
4895 }
4896 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004897 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898
4899 // Extract the command's parameter after the window description
4900 if (index < parameters.length()) {
4901 parameters = parameters.substring(index + 1);
4902 } else {
4903 parameters = "";
4904 }
4905
4906 final WindowManagerService.WindowState window = findWindow(hashCode);
4907 if (window == null) {
4908 return false;
4909 }
4910
4911 data = Parcel.obtain();
4912 data.writeInterfaceToken("android.view.IWindow");
4913 data.writeString(command);
4914 data.writeString(parameters);
4915 data.writeInt(1);
4916 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4917
4918 reply = Parcel.obtain();
4919
4920 final IBinder binder = window.mClient.asBinder();
4921 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4922 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4923
4924 reply.readException();
4925
4926 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004927 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 success = false;
4929 } finally {
4930 if (data != null) {
4931 data.recycle();
4932 }
4933 if (reply != null) {
4934 reply.recycle();
4935 }
4936 }
4937
4938 return success;
4939 }
4940
4941 private WindowState findWindow(int hashCode) {
4942 if (hashCode == -1) {
4943 return getFocusedWindow();
4944 }
4945
4946 synchronized (mWindowMap) {
4947 final ArrayList windows = mWindows;
4948 final int count = windows.size();
4949
4950 for (int i = 0; i < count; i++) {
4951 WindowState w = (WindowState) windows.get(i);
4952 if (System.identityHashCode(w) == hashCode) {
4953 return w;
4954 }
4955 }
4956 }
4957
4958 return null;
4959 }
4960
4961 /*
4962 * Instruct the Activity Manager to fetch the current configuration and broadcast
4963 * that to config-changed listeners if appropriate.
4964 */
4965 void sendNewConfiguration() {
4966 try {
4967 mActivityManager.updateConfiguration(null);
4968 } catch (RemoteException e) {
4969 }
4970 }
Romain Guy06882f82009-06-10 13:36:04 -07004971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 public Configuration computeNewConfiguration() {
4973 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07004974 return computeNewConfigurationLocked();
4975 }
4976 }
Romain Guy06882f82009-06-10 13:36:04 -07004977
Dianne Hackbornc485a602009-03-24 22:39:49 -07004978 Configuration computeNewConfigurationLocked() {
4979 Configuration config = new Configuration();
4980 if (!computeNewConfigurationLocked(config)) {
4981 return null;
4982 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07004983 return config;
4984 }
Romain Guy06882f82009-06-10 13:36:04 -07004985
Dianne Hackbornc485a602009-03-24 22:39:49 -07004986 boolean computeNewConfigurationLocked(Configuration config) {
4987 if (mDisplay == null) {
4988 return false;
4989 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004990 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4991 mInputManager.getInputConfiguration(config);
4992 } else {
4993 mQueue.getInputConfiguration(config);
4994 }
Christopher Tateb696aee2010-04-02 19:08:30 -07004995
4996 // Use the effective "visual" dimensions based on current rotation
4997 final boolean rotated = (mRotation == Surface.ROTATION_90
4998 || mRotation == Surface.ROTATION_270);
4999 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5000 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5001
Dianne Hackbornc485a602009-03-24 22:39:49 -07005002 int orientation = Configuration.ORIENTATION_SQUARE;
5003 if (dw < dh) {
5004 orientation = Configuration.ORIENTATION_PORTRAIT;
5005 } else if (dw > dh) {
5006 orientation = Configuration.ORIENTATION_LANDSCAPE;
5007 }
5008 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005009
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005010 DisplayMetrics dm = new DisplayMetrics();
5011 mDisplay.getMetrics(dm);
5012 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5013
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005014 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005015 // Note we only do this once because at this point we don't
5016 // expect the screen to change in this way at runtime, and want
5017 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005018 int longSize = dw;
5019 int shortSize = dh;
5020 if (longSize < shortSize) {
5021 int tmp = longSize;
5022 longSize = shortSize;
5023 shortSize = tmp;
5024 }
5025 longSize = (int)(longSize/dm.density);
5026 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005027
Dianne Hackborn723738c2009-06-25 19:48:04 -07005028 // These semi-magic numbers define our compatibility modes for
5029 // applications with different screens. Don't change unless you
5030 // make sure to test lots and lots of apps!
5031 if (longSize < 470) {
5032 // This is shorter than an HVGA normal density screen (which
5033 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005034 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5035 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005036 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005037 // What size is this screen screen?
5038 if (longSize >= 800 && shortSize >= 600) {
5039 // SVGA or larger screens at medium density are the point
5040 // at which we consider it to be an extra large screen.
5041 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5042 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005043 // VGA or larger screens at medium density are the point
5044 // at which we consider it to be a large screen.
5045 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5046 } else {
5047 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005048
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005049 // If this screen is wider than normal HVGA, or taller
5050 // than FWVGA, then for old apps we want to run in size
5051 // compatibility mode.
5052 if (shortSize > 321 || longSize > 570) {
5053 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5054 }
5055 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005056
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005057 // Is this a long screen?
5058 if (((longSize*3)/5) >= (shortSize-1)) {
5059 // Anything wider than WVGA (5:3) is considering to be long.
5060 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5061 } else {
5062 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5063 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005064 }
5065 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005066 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005067
Dianne Hackbornc485a602009-03-24 22:39:49 -07005068 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5069 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5070 mPolicy.adjustConfigurationLw(config);
5071 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005072 }
Romain Guy06882f82009-06-10 13:36:04 -07005073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005074 // -------------------------------------------------------------
5075 // Input Events and Focus Management
5076 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005077
5078 public void getKeyEventTargets(InputTargetList inputTargets,
5079 KeyEvent event, int nature, int policyFlags) {
5080 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
5081
5082 // TODO what do we do with mDisplayFrozen?
5083 // TODO what do we do with focus.mToken.paused?
5084
5085 WindowState focus = getFocusedWindow();
5086 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
5087
5088 addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
5089 }
5090
5091 // Target of Motion events
5092 WindowState mTouchFocus;
5093
5094 // Windows above the target who would like to receive an "outside"
5095 // touch event for any down events outside of them.
5096 // (This is a linked list by way of WindowState.mNextOutsideTouch.)
5097 WindowState mOutsideTouchTargets;
5098
5099 private void clearTouchFocus() {
5100 mTouchFocus = null;
5101 mOutsideTouchTargets = null;
5102 }
5103
5104 public void getMotionEventTargets(InputTargetList inputTargets,
5105 MotionEvent event, int nature, int policyFlags) {
5106 if (nature == InputQueue.INPUT_EVENT_NATURE_TRACKBALL) {
5107 // More or less the same as for keys...
5108 WindowState focus = getFocusedWindow();
5109 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
5110
5111 addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
5112 return;
5113 }
5114
5115 int action = event.getAction();
5116
5117 // TODO detect cheek presses somewhere... either here or in native code
5118
5119 final boolean screenWasOff = (policyFlags & WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
5120
5121 WindowState target = mTouchFocus;
5122
5123 if (action == MotionEvent.ACTION_UP) {
5124 // let go of our target
5125 mPowerManager.logPointerUpEvent();
5126 clearTouchFocus();
5127 } else if (action == MotionEvent.ACTION_DOWN) {
5128 // acquire a new target
5129 mPowerManager.logPointerDownEvent();
5130
5131 synchronized (mWindowMap) {
5132 if (mTouchFocus != null) {
5133 // this is weird, we got a pen down, but we thought it was
5134 // already down!
5135 // XXX: We should probably send an ACTION_UP to the current
5136 // target.
5137 Slog.w(TAG, "Pointer down received while already down in: "
5138 + mTouchFocus);
5139 clearTouchFocus();
5140 }
5141
5142 // ACTION_DOWN is special, because we need to lock next events to
5143 // the window we'll land onto.
5144 final int x = (int) event.getX();
5145 final int y = (int) event.getY();
5146
5147 final ArrayList windows = mWindows;
5148 final int N = windows.size();
5149 WindowState topErrWindow = null;
5150 final Rect tmpRect = mTempRect;
5151 for (int i=N-1; i>=0; i--) {
5152 WindowState child = (WindowState)windows.get(i);
5153 //Slog.i(TAG, "Checking dispatch to: " + child);
5154 final int flags = child.mAttrs.flags;
5155 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
5156 if (topErrWindow == null) {
5157 topErrWindow = child;
5158 }
5159 }
5160 if (!child.isVisibleLw()) {
5161 //Slog.i(TAG, "Not visible!");
5162 continue;
5163 }
5164 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
5165 //Slog.i(TAG, "Not touchable!");
5166 if ((flags & WindowManager.LayoutParams
5167 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
5168 child.mNextOutsideTouch = mOutsideTouchTargets;
5169 mOutsideTouchTargets = child;
5170 }
5171 continue;
5172 }
5173 tmpRect.set(child.mFrame);
5174 if (child.mTouchableInsets == ViewTreeObserver
5175 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
5176 // The touch is inside of the window if it is
5177 // inside the frame, AND the content part of that
5178 // frame that was given by the application.
5179 tmpRect.left += child.mGivenContentInsets.left;
5180 tmpRect.top += child.mGivenContentInsets.top;
5181 tmpRect.right -= child.mGivenContentInsets.right;
5182 tmpRect.bottom -= child.mGivenContentInsets.bottom;
5183 } else if (child.mTouchableInsets == ViewTreeObserver
5184 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
5185 // The touch is inside of the window if it is
5186 // inside the frame, AND the visible part of that
5187 // frame that was given by the application.
5188 tmpRect.left += child.mGivenVisibleInsets.left;
5189 tmpRect.top += child.mGivenVisibleInsets.top;
5190 tmpRect.right -= child.mGivenVisibleInsets.right;
5191 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
5192 }
5193 final int touchFlags = flags &
5194 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5195 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
5196 if (tmpRect.contains(x, y) || touchFlags == 0) {
5197 //Slog.i(TAG, "Using this target!");
5198 if (!screenWasOff || (flags &
5199 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
5200 mTouchFocus = child;
5201 } else {
5202 //Slog.i(TAG, "Waking, skip!");
5203 mTouchFocus = null;
5204 }
5205 break;
5206 }
5207
5208 if ((flags & WindowManager.LayoutParams
5209 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
5210 child.mNextOutsideTouch = mOutsideTouchTargets;
5211 mOutsideTouchTargets = child;
5212 //Slog.i(TAG, "Adding to outside target list: " + child);
5213 }
5214 }
5215
5216 // if there's an error window but it's not accepting
5217 // focus (typically because it is not yet visible) just
5218 // wait for it -- any other focused window may in fact
5219 // be in ANR state.
5220 if (topErrWindow != null && mTouchFocus != topErrWindow) {
5221 mTouchFocus = null;
5222 }
5223 }
5224
5225 target = mTouchFocus;
5226 }
5227
5228 if (target != null) {
5229 wakeupIfNeeded(target, eventType(event));
5230 }
5231
5232 int targetFlags = 0;
5233 if (target == null) {
5234 // In this case we are either dropping the event, or have received
5235 // a move or up without a down. It is common to receive move
5236 // events in such a way, since this means the user is moving the
5237 // pointer without actually pressing down. All other cases should
5238 // be atypical, so let's log them.
5239 if (action != MotionEvent.ACTION_MOVE) {
5240 Slog.w(TAG, "No window to dispatch pointer action " + action);
5241 }
5242 } else {
5243 if ((target.mAttrs.flags &
5244 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5245 //target wants to ignore fat touch events
5246 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(event);
5247 //explicit flag to return without processing event further
5248 boolean returnFlag = false;
5249 if((action == MotionEvent.ACTION_DOWN)) {
5250 mFatTouch = false;
5251 if(cheekPress) {
5252 mFatTouch = true;
5253 returnFlag = true;
5254 }
5255 } else {
5256 if(action == MotionEvent.ACTION_UP) {
5257 if(mFatTouch) {
5258 //earlier even was invalid doesnt matter if current up is cheekpress or not
5259 mFatTouch = false;
5260 returnFlag = true;
5261 } else if(cheekPress) {
5262 //cancel the earlier event
5263 targetFlags |= InputTarget.FLAG_CANCEL;
5264 action = MotionEvent.ACTION_CANCEL;
5265 }
5266 } else if(action == MotionEvent.ACTION_MOVE) {
5267 if(mFatTouch) {
5268 //two cases here
5269 //an invalid down followed by 0 or moves(valid or invalid)
5270 //a valid down, invalid move, more moves. want to ignore till up
5271 returnFlag = true;
5272 } else if(cheekPress) {
5273 //valid down followed by invalid moves
5274 //an invalid move have to cancel earlier action
5275 targetFlags |= InputTarget.FLAG_CANCEL;
5276 action = MotionEvent.ACTION_CANCEL;
5277 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
5278 //note that the subsequent invalid moves will not get here
5279 mFatTouch = true;
5280 }
5281 }
5282 } //else if action
5283 if(returnFlag) {
5284 return;
5285 }
5286 } //end if target
5287 }
5288
5289 synchronized (mWindowMap) {
5290 if (target != null && ! target.isVisibleLw()) {
5291 target = null;
5292 }
5293
5294 if (action == MotionEvent.ACTION_DOWN) {
5295 while (mOutsideTouchTargets != null) {
5296 addInputTarget(inputTargets, mOutsideTouchTargets,
5297 InputTarget.FLAG_OUTSIDE | targetFlags);
5298 mOutsideTouchTargets = mOutsideTouchTargets.mNextOutsideTouch;
5299 }
5300 }
5301
5302 // If we sent an initial down to the wallpaper, then continue
5303 // sending events until the final up.
5304 // Alternately if we are on top of the wallpaper, then the wallpaper also
5305 // gets to see this movement.
5306 if (mSendingPointersToWallpaper ||
5307 (target != null && action == MotionEvent.ACTION_DOWN
5308 && mWallpaperTarget == target
5309 && target.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)) {
5310 int curTokenIndex = mWallpaperTokens.size();
5311 while (curTokenIndex > 0) {
5312 curTokenIndex--;
5313 WindowToken token = mWallpaperTokens.get(curTokenIndex);
5314 int curWallpaperIndex = token.windows.size();
5315 while (curWallpaperIndex > 0) {
5316 curWallpaperIndex--;
5317 WindowState wallpaper = token.windows.get(curWallpaperIndex);
5318 if ((wallpaper.mAttrs.flags &
5319 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
5320 continue;
5321 }
5322
5323 switch (action) {
5324 case MotionEvent.ACTION_DOWN:
5325 mSendingPointersToWallpaper = true;
5326 break;
5327 case MotionEvent.ACTION_UP:
5328 mSendingPointersToWallpaper = false;
5329 break;
5330 }
5331
5332 addInputTarget(inputTargets, wallpaper, targetFlags);
5333 }
5334 }
5335 }
5336
5337 if (target != null) {
5338 addInputTarget(inputTargets, target, InputTarget.FLAG_SYNC | targetFlags);
5339 }
5340 }
5341 }
5342
5343 private void addInputTarget(InputTargetList inputTargets, WindowState window, int flags) {
5344 if (window.mInputChannel == null) {
5345 return;
5346 }
5347
5348 long timeoutNanos = -1;
5349 IApplicationToken appToken = window.getAppToken();
5350
5351 if (appToken != null) {
5352 try {
5353 timeoutNanos = appToken.getKeyDispatchingTimeout() * 1000000;
5354 } catch (RemoteException ex) {
5355 Slog.w(TAG, "Could not get key dispatching timeout.", ex);
5356 }
5357 }
5358
5359 inputTargets.add(window.mInputChannel, flags, timeoutNanos,
5360 - window.mFrame.left, - window.mFrame.top);
5361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005362
5363 private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
Michael Chane96440f2009-05-06 10:27:36 -07005364 long curTime = SystemClock.uptimeMillis();
5365
Michael Chane10de972009-05-18 11:24:50 -07005366 if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
Michael Chane96440f2009-05-06 10:27:36 -07005367 if (mLastTouchEventType == eventType &&
5368 (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
5369 return;
5370 }
5371 mLastUserActivityCallTime = curTime;
5372 mLastTouchEventType = eventType;
5373 }
5374
5375 if (targetWin == null
5376 || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
5377 mPowerManager.userActivity(curTime, false, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005378 }
5379 }
5380
5381 // tells if it's a cheek event or not -- this function is stateful
5382 private static final int EVENT_NONE = 0;
5383 private static final int EVENT_UNKNOWN = 0;
5384 private static final int EVENT_CHEEK = 0;
5385 private static final int EVENT_IGNORE_DURATION = 300; // ms
5386 private static final float CHEEK_THRESHOLD = 0.6f;
5387 private int mEventState = EVENT_NONE;
5388 private float mEventSize;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 private int eventType(MotionEvent ev) {
5391 float size = ev.getSize();
5392 switch (ev.getAction()) {
5393 case MotionEvent.ACTION_DOWN:
5394 mEventSize = size;
5395 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
5396 case MotionEvent.ACTION_UP:
5397 if (size > mEventSize) mEventSize = size;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005398 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 case MotionEvent.ACTION_MOVE:
5400 final int N = ev.getHistorySize();
5401 if (size > mEventSize) mEventSize = size;
5402 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5403 for (int i=0; i<N; i++) {
5404 size = ev.getHistoricalSize(i);
5405 if (size > mEventSize) mEventSize = size;
5406 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5407 }
5408 if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
5409 return TOUCH_EVENT;
5410 } else {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005411 return LONG_TOUCH_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 }
5413 default:
5414 // not good
5415 return OTHER_EVENT;
5416 }
5417 }
5418
5419 /**
5420 * @return Returns true if event was dispatched, false if it was dropped for any reason
5421 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005422 private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005423 if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 "dispatchPointer " + ev);
5425
Michael Chan53071d62009-05-13 17:29:48 -07005426 if (MEASURE_LATENCY) {
5427 lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
5428 }
5429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005431 ev, true, false, pid, uid);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005432
Michael Chan53071d62009-05-13 17:29:48 -07005433 if (MEASURE_LATENCY) {
5434 lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
5435 }
5436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005437 int action = ev.getAction();
Romain Guy06882f82009-06-10 13:36:04 -07005438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 if (action == MotionEvent.ACTION_UP) {
5440 // let go of our target
5441 mKeyWaiter.mMotionTarget = null;
5442 mPowerManager.logPointerUpEvent();
5443 } else if (action == MotionEvent.ACTION_DOWN) {
5444 mPowerManager.logPointerDownEvent();
5445 }
5446
5447 if (targetObj == null) {
5448 // In this case we are either dropping the event, or have received
5449 // a move or up without a down. It is common to receive move
5450 // events in such a way, since this means the user is moving the
5451 // pointer without actually pressing down. All other cases should
5452 // be atypical, so let's log them.
Michael Chane96440f2009-05-06 10:27:36 -07005453 if (action != MotionEvent.ACTION_MOVE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005454 Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 }
Dianne Hackborn6adba242009-11-10 11:10:09 -08005456 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005457 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005459 if (qev != null) {
5460 mQueue.recycleEvent(qev);
5461 }
5462 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005463 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 }
5465 if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005466 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005467 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005469 if (qev != null) {
5470 mQueue.recycleEvent(qev);
5471 }
5472 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005473 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 }
Romain Guy06882f82009-06-10 13:36:04 -07005475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 WindowState target = (WindowState)targetObj;
Romain Guy06882f82009-06-10 13:36:04 -07005477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005478 final long eventTime = ev.getEventTime();
Michael Chan53071d62009-05-13 17:29:48 -07005479 final long eventTimeNano = ev.getEventTimeNano();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005480
Joe Onorato8a9b2202010-02-26 18:56:32 -08005481 //Slog.i(TAG, "Sending " + ev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005482
5483 if (uid != 0 && uid != target.mSession.mUid) {
5484 if (mContext.checkPermission(
5485 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5486 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005487 Slog.w(TAG, "Permission denied: injecting pointer event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 + pid + " uid " + uid + " to window " + target
5489 + " owned by uid " + target.mSession.mUid);
5490 if (qev != null) {
5491 mQueue.recycleEvent(qev);
5492 }
5493 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005494 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 }
5496 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005497
Michael Chan53071d62009-05-13 17:29:48 -07005498 if (MEASURE_LATENCY) {
5499 lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5500 }
5501
Romain Guy06882f82009-06-10 13:36:04 -07005502 if ((target.mAttrs.flags &
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5504 //target wants to ignore fat touch events
5505 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
5506 //explicit flag to return without processing event further
5507 boolean returnFlag = false;
5508 if((action == MotionEvent.ACTION_DOWN)) {
5509 mFatTouch = false;
5510 if(cheekPress) {
5511 mFatTouch = true;
5512 returnFlag = true;
5513 }
5514 } else {
5515 if(action == MotionEvent.ACTION_UP) {
5516 if(mFatTouch) {
5517 //earlier even was invalid doesnt matter if current up is cheekpress or not
5518 mFatTouch = false;
5519 returnFlag = true;
5520 } else if(cheekPress) {
5521 //cancel the earlier event
5522 ev.setAction(MotionEvent.ACTION_CANCEL);
5523 action = MotionEvent.ACTION_CANCEL;
5524 }
5525 } else if(action == MotionEvent.ACTION_MOVE) {
5526 if(mFatTouch) {
5527 //two cases here
5528 //an invalid down followed by 0 or moves(valid or invalid)
Romain Guy06882f82009-06-10 13:36:04 -07005529 //a valid down, invalid move, more moves. want to ignore till up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005530 returnFlag = true;
5531 } else if(cheekPress) {
5532 //valid down followed by invalid moves
5533 //an invalid move have to cancel earlier action
5534 ev.setAction(MotionEvent.ACTION_CANCEL);
5535 action = MotionEvent.ACTION_CANCEL;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005536 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 //note that the subsequent invalid moves will not get here
5538 mFatTouch = true;
5539 }
5540 }
5541 } //else if action
5542 if(returnFlag) {
5543 //recycle que, ev
5544 if (qev != null) {
5545 mQueue.recycleEvent(qev);
5546 }
5547 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005548 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549 }
5550 } //end if target
Michael Chane96440f2009-05-06 10:27:36 -07005551
Michael Chan9f028e62009-08-04 17:37:46 -07005552 // Enable this for testing the "right" value
5553 if (false && action == MotionEvent.ACTION_DOWN) {
Michael Chane96440f2009-05-06 10:27:36 -07005554 int max_events_per_sec = 35;
5555 try {
5556 max_events_per_sec = Integer.parseInt(SystemProperties
5557 .get("windowsmgr.max_events_per_sec"));
5558 if (max_events_per_sec < 1) {
5559 max_events_per_sec = 35;
5560 }
5561 } catch (NumberFormatException e) {
5562 }
5563 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
5564 }
5565
5566 /*
5567 * Throttle events to minimize CPU usage when there's a flood of events
5568 * e.g. constant contact with the screen
5569 */
5570 if (action == MotionEvent.ACTION_MOVE) {
5571 long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
5572 long now = SystemClock.uptimeMillis();
5573 if (now < nextEventTime) {
5574 try {
5575 Thread.sleep(nextEventTime - now);
5576 } catch (InterruptedException e) {
5577 }
5578 mLastTouchEventTime = nextEventTime;
5579 } else {
5580 mLastTouchEventTime = now;
5581 }
5582 }
5583
Michael Chan53071d62009-05-13 17:29:48 -07005584 if (MEASURE_LATENCY) {
5585 lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5586 }
5587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005588 synchronized(mWindowMap) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005589 if (!target.isVisibleLw()) {
5590 // During this motion dispatch, the target window has become
5591 // invisible.
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005592 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005593 if (qev != null) {
5594 mQueue.recycleEvent(qev);
5595 }
5596 ev.recycle();
5597 return INJECT_SUCCEEDED;
5598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005600 if (qev != null && action == MotionEvent.ACTION_MOVE) {
5601 mKeyWaiter.bindTargetWindowLocked(target,
5602 KeyWaiter.RETURN_PENDING_POINTER, qev);
5603 ev = null;
5604 } else {
5605 if (action == MotionEvent.ACTION_DOWN) {
5606 WindowState out = mKeyWaiter.mOutsideTouchTargets;
5607 if (out != null) {
5608 MotionEvent oev = MotionEvent.obtain(ev);
Adam Powell47482962010-05-27 15:19:58 -07005609 try {
5610 oev.setAction(MotionEvent.ACTION_OUTSIDE);
5611 do {
5612 final Rect frame = out.mFrame;
5613 oev.offsetLocation(-(float)frame.left, -(float)frame.top);
5614 try {
5615 out.mClient.dispatchPointer(oev, eventTime, false);
5616 } catch (android.os.RemoteException e) {
5617 Slog.i(TAG,
5618 "WINDOW DIED during outside motion dispatch: " + out);
5619 }
5620 oev.offsetLocation((float)frame.left, (float)frame.top);
5621 out = out.mNextOutsideTouch;
5622 } while (out != null);
5623 mKeyWaiter.mOutsideTouchTargets = null;
5624 } finally {
5625 oev.recycle();
5626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005627 }
5628 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005629
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005630 dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005631
Dianne Hackborn6adba242009-11-10 11:10:09 -08005632 final Rect frame = target.mFrame;
5633 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
5634 mKeyWaiter.bindTargetWindowLocked(target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005635 }
5636 }
Romain Guy06882f82009-06-10 13:36:04 -07005637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 // finally offset the event to the target's coordinate system and
5639 // dispatch the event.
5640 try {
5641 if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005642 Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005644
Michael Chan53071d62009-05-13 17:29:48 -07005645 if (MEASURE_LATENCY) {
5646 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
5647 }
5648
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005649 target.mClient.dispatchPointer(ev, eventTime, true);
Michael Chan53071d62009-05-13 17:29:48 -07005650
5651 if (MEASURE_LATENCY) {
5652 lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
5653 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005654 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005656 Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005657 mKeyWaiter.mMotionTarget = null;
5658 try {
5659 removeWindow(target.mSession, target.mClient);
5660 } catch (java.util.NoSuchElementException ex) {
5661 // This will happen if the window has already been
5662 // removed.
5663 }
5664 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005665 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 }
Romain Guy06882f82009-06-10 13:36:04 -07005667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005668 /**
5669 * @return Returns true if event was dispatched, false if it was dropped for any reason
5670 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005671 private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
Romain Guy06882f82009-06-10 13:36:04 -07005674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005676 ev, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005678 Slog.w(TAG, "No focus window, dropping trackball: " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005679 if (qev != null) {
5680 mQueue.recycleEvent(qev);
5681 }
5682 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005683 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005684 }
5685 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
5686 if (qev != null) {
5687 mQueue.recycleEvent(qev);
5688 }
5689 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005690 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005691 }
Romain Guy06882f82009-06-10 13:36:04 -07005692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005693 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 if (uid != 0 && uid != focus.mSession.mUid) {
5696 if (mContext.checkPermission(
5697 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5698 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005699 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 + pid + " uid " + uid + " to window " + focus
5701 + " owned by uid " + focus.mSession.mUid);
5702 if (qev != null) {
5703 mQueue.recycleEvent(qev);
5704 }
5705 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005706 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005707 }
5708 }
Romain Guy06882f82009-06-10 13:36:04 -07005709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 final long eventTime = ev.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 synchronized(mWindowMap) {
5713 if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
5714 mKeyWaiter.bindTargetWindowLocked(focus,
5715 KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
5716 // We don't deliver movement events to the client, we hold
5717 // them and wait for them to call back.
5718 ev = null;
5719 } else {
5720 mKeyWaiter.bindTargetWindowLocked(focus);
5721 }
5722 }
Romain Guy06882f82009-06-10 13:36:04 -07005723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005725 focus.mClient.dispatchTrackball(ev, eventTime, true);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005726 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005727 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005728 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729 try {
5730 removeWindow(focus.mSession, focus.mClient);
5731 } catch (java.util.NoSuchElementException ex) {
5732 // This will happen if the window has already been
5733 // removed.
5734 }
5735 }
Romain Guy06882f82009-06-10 13:36:04 -07005736
Dianne Hackborncfaef692009-06-15 14:24:44 -07005737 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005738 }
Romain Guy06882f82009-06-10 13:36:04 -07005739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 /**
5741 * @return Returns true if event was dispatched, false if it was dropped for any reason
5742 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005743 private int dispatchKey(KeyEvent event, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005744 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005745
5746 Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005747 null, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005749 Slog.w(TAG, "No focus window, dropping: " + event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005750 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 }
5752 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005753 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005754 }
Romain Guy06882f82009-06-10 13:36:04 -07005755
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07005756 // Okay we have finished waiting for the last event to be processed.
5757 // First off, if this is a repeat event, check to see if there is
5758 // a corresponding up event in the queue. If there is, we will
5759 // just drop the repeat, because it makes no sense to repeat after
5760 // the user has released a key. (This is especially important for
5761 // long presses.)
5762 if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
5763 return INJECT_SUCCEEDED;
5764 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005767
Joe Onorato8a9b2202010-02-26 18:56:32 -08005768 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005769 TAG, "Dispatching to " + focus + ": " + event);
5770
5771 if (uid != 0 && uid != focus.mSession.mUid) {
5772 if (mContext.checkPermission(
5773 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5774 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005775 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 + pid + " uid " + uid + " to window " + focus
5777 + " owned by uid " + focus.mSession.mUid);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005778 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 }
5780 }
Romain Guy06882f82009-06-10 13:36:04 -07005781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 synchronized(mWindowMap) {
5783 mKeyWaiter.bindTargetWindowLocked(focus);
5784 }
5785
5786 // NOSHIP extra state logging
5787 mKeyWaiter.recordDispatchState(event, focus);
5788 // END NOSHIP
Romain Guy06882f82009-06-10 13:36:04 -07005789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 try {
5791 if (DEBUG_INPUT || DEBUG_FOCUS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005792 Slog.v(TAG, "Delivering key " + event.getKeyCode()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 + " to " + focus);
5794 }
5795 focus.mClient.dispatchKey(event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005796 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005798 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 try {
5800 removeWindow(focus.mSession, focus.mClient);
5801 } catch (java.util.NoSuchElementException ex) {
5802 // This will happen if the window has already been
5803 // removed.
5804 }
5805 }
Romain Guy06882f82009-06-10 13:36:04 -07005806
Dianne Hackborncfaef692009-06-15 14:24:44 -07005807 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 }
Romain Guy06882f82009-06-10 13:36:04 -07005809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 public void pauseKeyDispatching(IBinder _token) {
5811 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5812 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005813 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 }
5815
5816 synchronized (mWindowMap) {
5817 WindowToken token = mTokenMap.get(_token);
5818 if (token != null) {
5819 mKeyWaiter.pauseDispatchingLocked(token);
5820 }
5821 }
5822 }
5823
5824 public void resumeKeyDispatching(IBinder _token) {
5825 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5826 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005827 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005828 }
5829
5830 synchronized (mWindowMap) {
5831 WindowToken token = mTokenMap.get(_token);
5832 if (token != null) {
5833 mKeyWaiter.resumeDispatchingLocked(token);
5834 }
5835 }
5836 }
5837
5838 public void setEventDispatching(boolean enabled) {
5839 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5840 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005841 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842 }
5843
5844 synchronized (mWindowMap) {
5845 mKeyWaiter.setEventDispatchingLocked(enabled);
5846 }
5847 }
Romain Guy06882f82009-06-10 13:36:04 -07005848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005849 /**
5850 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005851 *
5852 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 * {@link SystemClock#uptimeMillis()} as the timebase.)
5854 * @param sync If true, wait for the event to be completed before returning to the caller.
5855 * @return Returns true if event was dispatched, false if it was dropped for any reason
5856 */
5857 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5858 long downTime = ev.getDownTime();
5859 long eventTime = ev.getEventTime();
5860
5861 int action = ev.getAction();
5862 int code = ev.getKeyCode();
5863 int repeatCount = ev.getRepeatCount();
5864 int metaState = ev.getMetaState();
5865 int deviceId = ev.getDeviceId();
5866 int scancode = ev.getScanCode();
5867
5868 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5869 if (downTime == 0) downTime = eventTime;
5870
5871 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07005872 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005873
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005874 final int pid = Binder.getCallingPid();
5875 final int uid = Binder.getCallingUid();
5876 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005877
5878 final int result;
5879 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5880 result = mInputManager.injectKeyEvent(newEvent,
5881 InputQueue.INPUT_EVENT_NATURE_KEY, sync, pid, uid);
5882 } else {
5883 result = dispatchKey(newEvent, pid, uid);
5884 if (sync) {
5885 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005888
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005889 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005890 switch (result) {
5891 case INJECT_NO_PERMISSION:
5892 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305893 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005894 case INJECT_SUCCEEDED:
5895 return true;
5896 }
5897 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005898 }
5899
5900 /**
5901 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005902 *
5903 * @param ev A motion event describing the pointer (touch) action. (As noted in
5904 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 * {@link SystemClock#uptimeMillis()} as the timebase.)
5906 * @param sync If true, wait for the event to be completed before returning to the caller.
5907 * @return Returns true if event was dispatched, false if it was dropped for any reason
5908 */
5909 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005910 final int pid = Binder.getCallingPid();
5911 final int uid = Binder.getCallingUid();
5912 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005913
5914 final int result;
5915 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5916 result = mInputManager.injectMotionEvent(ev,
5917 InputQueue.INPUT_EVENT_NATURE_TOUCH, sync, pid, uid);
5918 } else {
5919 result = dispatchPointer(null, ev, pid, uid);
5920 if (sync) {
5921 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005924
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005925 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005926 switch (result) {
5927 case INJECT_NO_PERMISSION:
5928 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305929 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005930 case INJECT_SUCCEEDED:
5931 return true;
5932 }
5933 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005934 }
Romain Guy06882f82009-06-10 13:36:04 -07005935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 /**
5937 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005938 *
5939 * @param ev A motion event describing the trackball action. (As noted in
5940 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 * {@link SystemClock#uptimeMillis()} as the timebase.)
5942 * @param sync If true, wait for the event to be completed before returning to the caller.
5943 * @return Returns true if event was dispatched, false if it was dropped for any reason
5944 */
5945 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005946 final int pid = Binder.getCallingPid();
5947 final int uid = Binder.getCallingUid();
5948 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005949
5950 final int result;
5951 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5952 result = mInputManager.injectMotionEvent(ev,
5953 InputQueue.INPUT_EVENT_NATURE_TRACKBALL, sync, pid, uid);
5954 } else {
5955 result = dispatchTrackball(null, ev, pid, uid);
5956 if (sync) {
5957 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005959 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005960
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005961 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005962 switch (result) {
5963 case INJECT_NO_PERMISSION:
5964 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305965 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005966 case INJECT_SUCCEEDED:
5967 return true;
5968 }
5969 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005970 }
Romain Guy06882f82009-06-10 13:36:04 -07005971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005972 private WindowState getFocusedWindow() {
5973 synchronized (mWindowMap) {
5974 return getFocusedWindowLocked();
5975 }
5976 }
5977
5978 private WindowState getFocusedWindowLocked() {
5979 return mCurrentFocus;
5980 }
Romain Guy06882f82009-06-10 13:36:04 -07005981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 /**
5983 * This class holds the state for dispatching key events. This state
5984 * is protected by the KeyWaiter instance, NOT by the window lock. You
5985 * can be holding the main window lock while acquire the KeyWaiter lock,
5986 * but not the other way around.
5987 */
5988 final class KeyWaiter {
5989 // NOSHIP debugging
5990 public class DispatchState {
5991 private KeyEvent event;
5992 private WindowState focus;
5993 private long time;
5994 private WindowState lastWin;
5995 private IBinder lastBinder;
5996 private boolean finished;
5997 private boolean gotFirstWindow;
5998 private boolean eventDispatching;
5999 private long timeToSwitch;
6000 private boolean wasFrozen;
6001 private boolean focusPaused;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006002 private WindowState curFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004 DispatchState(KeyEvent theEvent, WindowState theFocus) {
6005 focus = theFocus;
6006 event = theEvent;
6007 time = System.currentTimeMillis();
6008 // snapshot KeyWaiter state
6009 lastWin = mLastWin;
6010 lastBinder = mLastBinder;
6011 finished = mFinished;
6012 gotFirstWindow = mGotFirstWindow;
6013 eventDispatching = mEventDispatching;
6014 timeToSwitch = mTimeToSwitch;
6015 wasFrozen = mWasFrozen;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006016 curFocus = mCurrentFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006017 // cache the paused state at ctor time as well
6018 if (theFocus == null || theFocus.mToken == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 focusPaused = false;
6020 } else {
6021 focusPaused = theFocus.mToken.paused;
6022 }
6023 }
Romain Guy06882f82009-06-10 13:36:04 -07006024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 public String toString() {
6026 return "{{" + event + " to " + focus + " @ " + time
6027 + " lw=" + lastWin + " lb=" + lastBinder
6028 + " fin=" + finished + " gfw=" + gotFirstWindow
6029 + " ed=" + eventDispatching + " tts=" + timeToSwitch
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006030 + " wf=" + wasFrozen + " fp=" + focusPaused
Christopher Tate46d45252010-02-09 15:48:57 -08006031 + " mcf=" + curFocus + "}}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006032 }
6033 };
6034 private DispatchState mDispatchState = null;
6035 public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
6036 mDispatchState = new DispatchState(theEvent, theFocus);
6037 }
6038 // END NOSHIP
6039
6040 public static final int RETURN_NOTHING = 0;
6041 public static final int RETURN_PENDING_POINTER = 1;
6042 public static final int RETURN_PENDING_TRACKBALL = 2;
Romain Guy06882f82009-06-10 13:36:04 -07006043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006044 final Object SKIP_TARGET_TOKEN = new Object();
6045 final Object CONSUMED_EVENT_TOKEN = new Object();
Romain Guy06882f82009-06-10 13:36:04 -07006046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006047 private WindowState mLastWin = null;
6048 private IBinder mLastBinder = null;
6049 private boolean mFinished = true;
6050 private boolean mGotFirstWindow = false;
6051 private boolean mEventDispatching = true;
6052 private long mTimeToSwitch = 0;
6053 /* package */ boolean mWasFrozen = false;
Romain Guy06882f82009-06-10 13:36:04 -07006054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 // Target of Motion events
6056 WindowState mMotionTarget;
Romain Guy06882f82009-06-10 13:36:04 -07006057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 // Windows above the target who would like to receive an "outside"
6059 // touch event for any down events outside of them.
6060 WindowState mOutsideTouchTargets;
6061
6062 /**
6063 * Wait for the last event dispatch to complete, then find the next
6064 * target that should receive the given event and wait for that one
6065 * to be ready to receive it.
6066 */
6067 Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
6068 MotionEvent nextMotion, boolean isPointerEvent,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006069 boolean failIfTimeout, int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 long startTime = SystemClock.uptimeMillis();
6071 long keyDispatchingTimeout = 5 * 1000;
6072 long waitedFor = 0;
6073
6074 while (true) {
6075 // Figure out which window we care about. It is either the
6076 // last window we are waiting to have process the event or,
6077 // if none, then the next window we think the event should go
6078 // to. Note: we retrieve mLastWin outside of the lock, so
6079 // it may change before we lock. Thus we must check it again.
6080 WindowState targetWin = mLastWin;
6081 boolean targetIsNew = targetWin == null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006082 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 TAG, "waitForLastKey: mFinished=" + mFinished +
6084 ", mLastWin=" + mLastWin);
6085 if (targetIsNew) {
6086 Object target = findTargetWindow(nextKey, qev, nextMotion,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006087 isPointerEvent, callingPid, callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 if (target == SKIP_TARGET_TOKEN) {
6089 // The user has pressed a special key, and we are
6090 // dropping all pending events before it.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006091 if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 + " " + nextMotion);
6093 return null;
6094 }
6095 if (target == CONSUMED_EVENT_TOKEN) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006096 if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 + " " + nextMotion);
6098 return target;
6099 }
6100 targetWin = (WindowState)target;
6101 }
Romain Guy06882f82009-06-10 13:36:04 -07006102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 AppWindowToken targetApp = null;
Romain Guy06882f82009-06-10 13:36:04 -07006104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 // Now: is it okay to send the next event to this window?
6106 synchronized (this) {
6107 // First: did we come here based on the last window not
6108 // being null, but it changed by the time we got here?
6109 // If so, try again.
6110 if (!targetIsNew && mLastWin == null) {
6111 continue;
6112 }
Romain Guy06882f82009-06-10 13:36:04 -07006113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006114 // We never dispatch events if not finished with the
6115 // last one, or the display is frozen.
6116 if (mFinished && !mDisplayFrozen) {
6117 // If event dispatching is disabled, then we
6118 // just consume the events.
6119 if (!mEventDispatching) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006120 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006121 "Skipping event; dispatching disabled: "
6122 + nextKey + " " + nextMotion);
6123 return null;
6124 }
6125 if (targetWin != null) {
6126 // If this is a new target, and that target is not
6127 // paused or unresponsive, then all looks good to
6128 // handle the event.
6129 if (targetIsNew && !targetWin.mToken.paused) {
6130 return targetWin;
6131 }
Romain Guy06882f82009-06-10 13:36:04 -07006132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 // If we didn't find a target window, and there is no
6134 // focused app window, then just eat the events.
6135 } else if (mFocusedApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006136 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137 "Skipping event; no focused app: "
6138 + nextKey + " " + nextMotion);
6139 return null;
6140 }
6141 }
Romain Guy06882f82009-06-10 13:36:04 -07006142
Joe Onorato8a9b2202010-02-26 18:56:32 -08006143 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 TAG, "Waiting for last key in " + mLastBinder
6145 + " target=" + targetWin
6146 + " mFinished=" + mFinished
6147 + " mDisplayFrozen=" + mDisplayFrozen
6148 + " targetIsNew=" + targetIsNew
6149 + " paused="
6150 + (targetWin != null ? targetWin.mToken.paused : false)
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006151 + " mFocusedApp=" + mFocusedApp
6152 + " mCurrentFocus=" + mCurrentFocus);
Romain Guy06882f82009-06-10 13:36:04 -07006153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 targetApp = targetWin != null
6155 ? targetWin.mAppToken : mFocusedApp;
Romain Guy06882f82009-06-10 13:36:04 -07006156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006157 long curTimeout = keyDispatchingTimeout;
6158 if (mTimeToSwitch != 0) {
6159 long now = SystemClock.uptimeMillis();
6160 if (mTimeToSwitch <= now) {
6161 // If an app switch key has been pressed, and we have
6162 // waited too long for the current app to finish
6163 // processing keys, then wait no more!
Christopher Tate136b1f92010-02-11 17:51:24 -08006164 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 continue;
6166 }
6167 long switchTimeout = mTimeToSwitch - now;
6168 if (curTimeout > switchTimeout) {
6169 curTimeout = switchTimeout;
6170 }
6171 }
Romain Guy06882f82009-06-10 13:36:04 -07006172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 try {
6174 // after that continue
6175 // processing keys, so we don't get stuck.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006176 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 TAG, "Waiting for key dispatch: " + curTimeout);
6178 wait(curTimeout);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006179 if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006180 + SystemClock.uptimeMillis() + " startTime="
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006181 + startTime + " switchTime=" + mTimeToSwitch
6182 + " target=" + targetWin + " mLW=" + mLastWin
6183 + " mLB=" + mLastBinder + " fin=" + mFinished
6184 + " mCurrentFocus=" + mCurrentFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006185 } catch (InterruptedException e) {
6186 }
6187 }
6188
6189 // If we were frozen during configuration change, restart the
6190 // timeout checks from now; otherwise look at whether we timed
6191 // out before awakening.
6192 if (mWasFrozen) {
6193 waitedFor = 0;
6194 mWasFrozen = false;
6195 } else {
6196 waitedFor = SystemClock.uptimeMillis() - startTime;
6197 }
6198
6199 if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
6200 IApplicationToken at = null;
6201 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006202 Slog.w(TAG, "Key dispatching timed out sending to " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 (targetWin != null ? targetWin.mAttrs.getTitle()
Ken Shirriff8200b202010-02-04 13:34:37 -08006204 : "<null>: no window ready for key dispatch"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006205 // NOSHIP debugging
Joe Onorato8a9b2202010-02-26 18:56:32 -08006206 Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
6207 Slog.w(TAG, "Current dispatch state: " +
Ken Shirriff8200b202010-02-04 13:34:37 -08006208 new DispatchState(nextKey, targetWin));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 // END NOSHIP
6210 //dump();
6211 if (targetWin != null) {
6212 at = targetWin.getAppToken();
6213 } else if (targetApp != null) {
6214 at = targetApp.appToken;
6215 }
6216 }
6217
6218 boolean abort = true;
6219 if (at != null) {
6220 try {
6221 long timeout = at.getKeyDispatchingTimeout();
6222 if (timeout > waitedFor) {
6223 // we did not wait the proper amount of time for this application.
6224 // set the timeout to be the real timeout and wait again.
6225 keyDispatchingTimeout = timeout - waitedFor;
6226 continue;
6227 } else {
6228 abort = at.keyDispatchingTimedOut();
6229 }
6230 } catch (RemoteException ex) {
6231 }
6232 }
6233
6234 synchronized (this) {
6235 if (abort && (mLastWin == targetWin || targetWin == null)) {
6236 mFinished = true;
Romain Guy06882f82009-06-10 13:36:04 -07006237 if (mLastWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006238 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006239 "Window " + mLastWin +
6240 " timed out on key input");
6241 if (mLastWin.mToken.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006242 Slog.w(TAG, "Un-pausing dispatching to this window");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006243 mLastWin.mToken.paused = false;
6244 }
6245 }
6246 if (mMotionTarget == targetWin) {
6247 mMotionTarget = null;
6248 }
6249 mLastWin = null;
6250 mLastBinder = null;
6251 if (failIfTimeout || targetWin == null) {
6252 return null;
6253 }
6254 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006255 Slog.w(TAG, "Continuing to wait for key to be dispatched");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 startTime = SystemClock.uptimeMillis();
6257 }
6258 }
6259 }
6260 }
6261 }
Romain Guy06882f82009-06-10 13:36:04 -07006262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006264 MotionEvent nextMotion, boolean isPointerEvent,
6265 int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006266 mOutsideTouchTargets = null;
Romain Guy06882f82009-06-10 13:36:04 -07006267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006268 if (nextKey != null) {
6269 // Find the target window for a normal key event.
6270 final int keycode = nextKey.getKeyCode();
6271 final int repeatCount = nextKey.getRepeatCount();
6272 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
6273 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 if (!dispatch) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006276 if (callingUid == 0 ||
6277 mContext.checkPermission(
6278 android.Manifest.permission.INJECT_EVENTS,
6279 callingPid, callingUid)
6280 == PackageManager.PERMISSION_GRANTED) {
6281 mPolicy.interceptKeyTi(null, keycode,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006282 nextKey.getMetaState(), down, repeatCount,
6283 nextKey.getFlags());
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006284 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006285 Slog.w(TAG, "Event timeout during app switch: dropping "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006286 + nextKey);
6287 return SKIP_TARGET_TOKEN;
6288 }
Romain Guy06882f82009-06-10 13:36:04 -07006289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
Romain Guy06882f82009-06-10 13:36:04 -07006291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006292 WindowState focus = null;
6293 synchronized(mWindowMap) {
6294 focus = getFocusedWindowLocked();
6295 }
Romain Guy06882f82009-06-10 13:36:04 -07006296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
Romain Guy06882f82009-06-10 13:36:04 -07006298
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006299 if (callingUid == 0 ||
6300 (focus != null && callingUid == focus.mSession.mUid) ||
6301 mContext.checkPermission(
6302 android.Manifest.permission.INJECT_EVENTS,
6303 callingPid, callingUid)
6304 == PackageManager.PERMISSION_GRANTED) {
6305 if (mPolicy.interceptKeyTi(focus,
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006306 keycode, nextKey.getMetaState(), down, repeatCount,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006307 nextKey.getFlags())) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006308 return CONSUMED_EVENT_TOKEN;
6309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006310 }
Romain Guy06882f82009-06-10 13:36:04 -07006311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 return focus;
Romain Guy06882f82009-06-10 13:36:04 -07006313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 } else if (!isPointerEvent) {
6315 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
6316 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006317 Slog.w(TAG, "Event timeout during app switch: dropping trackball "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 + nextMotion);
6319 return SKIP_TARGET_TOKEN;
6320 }
Romain Guy06882f82009-06-10 13:36:04 -07006321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 WindowState focus = null;
6323 synchronized(mWindowMap) {
6324 focus = getFocusedWindowLocked();
6325 }
Romain Guy06882f82009-06-10 13:36:04 -07006326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
6328 return focus;
6329 }
Romain Guy06882f82009-06-10 13:36:04 -07006330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006331 if (nextMotion == null) {
6332 return SKIP_TARGET_TOKEN;
6333 }
Romain Guy06882f82009-06-10 13:36:04 -07006334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
6336 KeyEvent.KEYCODE_UNKNOWN);
6337 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006338 Slog.w(TAG, "Event timeout during app switch: dropping pointer "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 + nextMotion);
6340 return SKIP_TARGET_TOKEN;
6341 }
Romain Guy06882f82009-06-10 13:36:04 -07006342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006343 // Find the target window for a pointer event.
6344 int action = nextMotion.getAction();
6345 final float xf = nextMotion.getX();
6346 final float yf = nextMotion.getY();
6347 final long eventTime = nextMotion.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07006348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 final boolean screenWasOff = qev != null
6350 && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07006351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006352 WindowState target = null;
Romain Guy06882f82009-06-10 13:36:04 -07006353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006354 synchronized(mWindowMap) {
6355 synchronized (this) {
6356 if (action == MotionEvent.ACTION_DOWN) {
6357 if (mMotionTarget != null) {
6358 // this is weird, we got a pen down, but we thought it was
6359 // already down!
6360 // XXX: We should probably send an ACTION_UP to the current
6361 // target.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006362 Slog.w(TAG, "Pointer down received while already down in: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006363 + mMotionTarget);
6364 mMotionTarget = null;
6365 }
Romain Guy06882f82009-06-10 13:36:04 -07006366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 // ACTION_DOWN is special, because we need to lock next events to
6368 // the window we'll land onto.
6369 final int x = (int)xf;
6370 final int y = (int)yf;
Romain Guy06882f82009-06-10 13:36:04 -07006371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 final ArrayList windows = mWindows;
6373 final int N = windows.size();
6374 WindowState topErrWindow = null;
6375 final Rect tmpRect = mTempRect;
6376 for (int i=N-1; i>=0; i--) {
6377 WindowState child = (WindowState)windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006378 //Slog.i(TAG, "Checking dispatch to: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006379 final int flags = child.mAttrs.flags;
6380 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
6381 if (topErrWindow == null) {
6382 topErrWindow = child;
6383 }
6384 }
6385 if (!child.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006386 //Slog.i(TAG, "Not visible!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006387 continue;
6388 }
6389 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006390 //Slog.i(TAG, "Not touchable!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 if ((flags & WindowManager.LayoutParams
6392 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6393 child.mNextOutsideTouch = mOutsideTouchTargets;
6394 mOutsideTouchTargets = child;
6395 }
6396 continue;
6397 }
6398 tmpRect.set(child.mFrame);
6399 if (child.mTouchableInsets == ViewTreeObserver
6400 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
6401 // The touch is inside of the window if it is
6402 // inside the frame, AND the content part of that
6403 // frame that was given by the application.
6404 tmpRect.left += child.mGivenContentInsets.left;
6405 tmpRect.top += child.mGivenContentInsets.top;
6406 tmpRect.right -= child.mGivenContentInsets.right;
6407 tmpRect.bottom -= child.mGivenContentInsets.bottom;
6408 } else if (child.mTouchableInsets == ViewTreeObserver
6409 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
6410 // The touch is inside of the window if it is
6411 // inside the frame, AND the visible part of that
6412 // frame that was given by the application.
6413 tmpRect.left += child.mGivenVisibleInsets.left;
6414 tmpRect.top += child.mGivenVisibleInsets.top;
6415 tmpRect.right -= child.mGivenVisibleInsets.right;
6416 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
6417 }
6418 final int touchFlags = flags &
6419 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6420 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
6421 if (tmpRect.contains(x, y) || touchFlags == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006422 //Slog.i(TAG, "Using this target!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006423 if (!screenWasOff || (flags &
6424 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
6425 mMotionTarget = child;
6426 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006427 //Slog.i(TAG, "Waking, skip!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 mMotionTarget = null;
6429 }
6430 break;
6431 }
Romain Guy06882f82009-06-10 13:36:04 -07006432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006433 if ((flags & WindowManager.LayoutParams
6434 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6435 child.mNextOutsideTouch = mOutsideTouchTargets;
6436 mOutsideTouchTargets = child;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006437 //Slog.i(TAG, "Adding to outside target list: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 }
6439 }
6440
6441 // if there's an error window but it's not accepting
6442 // focus (typically because it is not yet visible) just
6443 // wait for it -- any other focused window may in fact
6444 // be in ANR state.
6445 if (topErrWindow != null && mMotionTarget != topErrWindow) {
6446 mMotionTarget = null;
6447 }
6448 }
Romain Guy06882f82009-06-10 13:36:04 -07006449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 target = mMotionTarget;
6451 }
6452 }
Romain Guy06882f82009-06-10 13:36:04 -07006453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 wakeupIfNeeded(target, eventType(nextMotion));
Romain Guy06882f82009-06-10 13:36:04 -07006455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006456 // Pointer events are a little different -- if there isn't a
6457 // target found for any event, then just drop it.
6458 return target != null ? target : SKIP_TARGET_TOKEN;
6459 }
Romain Guy06882f82009-06-10 13:36:04 -07006460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006461 boolean checkShouldDispatchKey(int keycode) {
6462 synchronized (this) {
6463 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
6464 mTimeToSwitch = 0;
6465 return true;
6466 }
6467 if (mTimeToSwitch != 0
6468 && mTimeToSwitch < SystemClock.uptimeMillis()) {
6469 return false;
6470 }
6471 return true;
6472 }
6473 }
Romain Guy06882f82009-06-10 13:36:04 -07006474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006475 void bindTargetWindowLocked(WindowState win,
6476 int pendingWhat, QueuedEvent pendingMotion) {
6477 synchronized (this) {
6478 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
6479 }
6480 }
Romain Guy06882f82009-06-10 13:36:04 -07006481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006482 void bindTargetWindowLocked(WindowState win) {
6483 synchronized (this) {
6484 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
6485 }
6486 }
6487
6488 void bindTargetWindowLockedLocked(WindowState win,
6489 int pendingWhat, QueuedEvent pendingMotion) {
6490 mLastWin = win;
6491 mLastBinder = win.mClient.asBinder();
6492 mFinished = false;
6493 if (pendingMotion != null) {
6494 final Session s = win.mSession;
6495 if (pendingWhat == RETURN_PENDING_POINTER) {
6496 releasePendingPointerLocked(s);
6497 s.mPendingPointerMove = pendingMotion;
6498 s.mPendingPointerWindow = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006499 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 "bindTargetToWindow " + s.mPendingPointerMove);
6501 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
6502 releasePendingTrackballLocked(s);
6503 s.mPendingTrackballMove = pendingMotion;
6504 s.mPendingTrackballWindow = win;
6505 }
6506 }
6507 }
Romain Guy06882f82009-06-10 13:36:04 -07006508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 void releasePendingPointerLocked(Session s) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006510 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511 "releasePendingPointer " + s.mPendingPointerMove);
6512 if (s.mPendingPointerMove != null) {
6513 mQueue.recycleEvent(s.mPendingPointerMove);
6514 s.mPendingPointerMove = null;
6515 }
6516 }
Romain Guy06882f82009-06-10 13:36:04 -07006517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006518 void releasePendingTrackballLocked(Session s) {
6519 if (s.mPendingTrackballMove != null) {
6520 mQueue.recycleEvent(s.mPendingTrackballMove);
6521 s.mPendingTrackballMove = null;
6522 }
6523 }
Romain Guy06882f82009-06-10 13:36:04 -07006524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006525 MotionEvent finishedKey(Session session, IWindow client, boolean force,
6526 int returnWhat) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006527 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006528 TAG, "finishedKey: client=" + client + ", force=" + force);
6529
6530 if (client == null) {
6531 return null;
6532 }
6533
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006534 MotionEvent res = null;
6535 QueuedEvent qev = null;
6536 WindowState win = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006539 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 TAG, "finishedKey: client=" + client.asBinder()
6541 + ", force=" + force + ", last=" + mLastBinder
6542 + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
6543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 if (returnWhat == RETURN_PENDING_POINTER) {
6545 qev = session.mPendingPointerMove;
6546 win = session.mPendingPointerWindow;
6547 session.mPendingPointerMove = null;
6548 session.mPendingPointerWindow = null;
6549 } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
6550 qev = session.mPendingTrackballMove;
6551 win = session.mPendingTrackballWindow;
6552 session.mPendingTrackballMove = null;
6553 session.mPendingTrackballWindow = null;
6554 }
Romain Guy06882f82009-06-10 13:36:04 -07006555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 if (mLastBinder == client.asBinder()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006557 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 TAG, "finishedKey: last paused="
6559 + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
6560 if (mLastWin != null && (!mLastWin.mToken.paused || force
6561 || !mEventDispatching)) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006562 doFinishedKeyLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006563 } else {
6564 // Make sure to wake up anyone currently waiting to
6565 // dispatch a key, so they can re-evaluate their
6566 // current situation.
6567 mFinished = true;
6568 notifyAll();
6569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006570 }
Romain Guy06882f82009-06-10 13:36:04 -07006571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006572 if (qev != null) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006573 res = (MotionEvent)qev.event;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006574 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006575 "Returning pending motion: " + res);
6576 mQueue.recycleEvent(qev);
6577 if (win != null && returnWhat == RETURN_PENDING_POINTER) {
6578 res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
6579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 }
Christopher Tate2624fbc2009-12-11 12:11:31 -08006581 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006582
Christopher Tate2624fbc2009-12-11 12:11:31 -08006583 if (res != null && returnWhat == RETURN_PENDING_POINTER) {
6584 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08006585 dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006586 }
6587 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006588
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006589 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 }
6591
6592 void tickle() {
6593 synchronized (this) {
6594 notifyAll();
6595 }
6596 }
Romain Guy06882f82009-06-10 13:36:04 -07006597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 void handleNewWindowLocked(WindowState newWindow) {
6599 if (!newWindow.canReceiveKeys()) {
6600 return;
6601 }
6602 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006603 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 TAG, "New key dispatch window: win="
6605 + newWindow.mClient.asBinder()
6606 + ", last=" + mLastBinder
6607 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6608 + "), finished=" + mFinished + ", paused="
6609 + newWindow.mToken.paused);
6610
6611 // Displaying a window implicitly causes dispatching to
6612 // be unpaused. (This is to protect against bugs if someone
6613 // pauses dispatching but forgets to resume.)
6614 newWindow.mToken.paused = false;
6615
6616 mGotFirstWindow = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617
6618 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006619 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 "New SYSTEM_ERROR window; resetting state");
6621 mLastWin = null;
6622 mLastBinder = null;
6623 mMotionTarget = null;
6624 mFinished = true;
6625 } else if (mLastWin != null) {
6626 // If the new window is above the window we are
6627 // waiting on, then stop waiting and let key dispatching
6628 // start on the new guy.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006629 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 TAG, "Last win layer=" + mLastWin.mLayer
6631 + ", new win layer=" + newWindow.mLayer);
6632 if (newWindow.mLayer >= mLastWin.mLayer) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006633 // The new window is above the old; finish pending input to the last
6634 // window and start directing it to the new one.
6635 mLastWin.mToken.paused = false;
Christopher Tate136b1f92010-02-11 17:51:24 -08006636 doFinishedKeyLocked(false); // does a notifyAll()
6637 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006638 }
6639 }
6640
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006641 // Now that we've put a new window state in place, make the event waiter
6642 // take notice and retarget its attentions.
6643 notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 }
6645 }
6646
6647 void pauseDispatchingLocked(WindowToken token) {
6648 synchronized (this)
6649 {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006650 if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 token.paused = true;
6652
6653 /*
6654 if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
6655 mPaused = true;
6656 } else {
6657 if (mLastWin == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006658 Slog.i(TAG, "Key dispatching not paused: no last window.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 } else if (mFinished) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006660 Slog.i(TAG, "Key dispatching not paused: finished last key.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006662 Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 }
6664 }
6665 */
6666 }
6667 }
6668
6669 void resumeDispatchingLocked(WindowToken token) {
6670 synchronized (this) {
6671 if (token.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006672 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 TAG, "Resuming WindowToken " + token
6674 + ", last=" + mLastBinder
6675 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6676 + "), finished=" + mFinished + ", paused="
6677 + token.paused);
6678 token.paused = false;
6679 if (mLastWin != null && mLastWin.mToken == token && mFinished) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006680 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 } else {
6682 notifyAll();
6683 }
6684 }
6685 }
6686 }
6687
6688 void setEventDispatchingLocked(boolean enabled) {
6689 synchronized (this) {
6690 mEventDispatching = enabled;
6691 notifyAll();
6692 }
6693 }
Romain Guy06882f82009-06-10 13:36:04 -07006694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 void appSwitchComing() {
6696 synchronized (this) {
6697 // Don't wait for more than .5 seconds for app to finish
6698 // processing the pending events.
6699 long now = SystemClock.uptimeMillis() + 500;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006700 if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
6702 mTimeToSwitch = now;
6703 }
6704 notifyAll();
6705 }
6706 }
Romain Guy06882f82009-06-10 13:36:04 -07006707
Christopher Tate136b1f92010-02-11 17:51:24 -08006708 private final void doFinishedKeyLocked(boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 if (mLastWin != null) {
6710 releasePendingPointerLocked(mLastWin.mSession);
6711 releasePendingTrackballLocked(mLastWin.mSession);
6712 }
Romain Guy06882f82009-06-10 13:36:04 -07006713
Christopher Tate136b1f92010-02-11 17:51:24 -08006714 if (force || mLastWin == null || !mLastWin.mToken.paused
6715 || !mLastWin.isVisibleLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 // If the current window has been paused, we aren't -really-
6717 // finished... so let the waiters still wait.
6718 mLastWin = null;
6719 mLastBinder = null;
6720 }
6721 mFinished = true;
6722 notifyAll();
6723 }
6724 }
6725
6726 private class KeyQ extends KeyInputQueue
6727 implements KeyInputQueue.FilterCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006728 KeyQ() {
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006729 super(mContext, WindowManagerService.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006730 }
6731
6732 @Override
6733 boolean preprocessEvent(InputDevice device, RawInputEvent event) {
6734 if (mPolicy.preprocessInputEventTq(event)) {
6735 return true;
6736 }
Romain Guy06882f82009-06-10 13:36:04 -07006737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006738 switch (event.type) {
6739 case RawInputEvent.EV_KEY: {
6740 // XXX begin hack
6741 if (DEBUG) {
6742 if (event.keycode == KeyEvent.KEYCODE_G) {
6743 if (event.value != 0) {
6744 // G down
6745 mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
6746 }
6747 return false;
6748 }
6749 if (event.keycode == KeyEvent.KEYCODE_D) {
6750 if (event.value != 0) {
6751 //dump();
6752 }
6753 return false;
6754 }
6755 }
6756 // XXX end hack
Romain Guy06882f82009-06-10 13:36:04 -07006757
Charles Mendis322591c2009-10-29 11:06:59 -07006758 boolean screenIsOff = !mPowerManager.isScreenOn();
6759 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006760 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
Romain Guy06882f82009-06-10 13:36:04 -07006761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
6763 mPowerManager.goToSleep(event.when);
6764 }
6765
6766 if (screenIsOff) {
6767 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6768 }
6769 if (screenIsDim) {
6770 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6771 }
6772 if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
6773 mPowerManager.userActivity(event.when, false,
Michael Chane96440f2009-05-06 10:27:36 -07006774 LocalPowerManager.BUTTON_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006775 }
Romain Guy06882f82009-06-10 13:36:04 -07006776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
6778 if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
6779 filterQueue(this);
6780 mKeyWaiter.appSwitchComing();
6781 }
6782 return true;
6783 } else {
6784 return false;
6785 }
6786 }
Romain Guy06882f82009-06-10 13:36:04 -07006787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 case RawInputEvent.EV_REL: {
Charles Mendis322591c2009-10-29 11:06:59 -07006789 boolean screenIsOff = !mPowerManager.isScreenOn();
6790 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 if (screenIsOff) {
6792 if (!mPolicy.isWakeRelMovementTq(event.deviceId,
6793 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006794 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 return false;
6796 }
6797 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6798 }
6799 if (screenIsDim) {
6800 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6801 }
6802 return true;
6803 }
Romain Guy06882f82009-06-10 13:36:04 -07006804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 case RawInputEvent.EV_ABS: {
Charles Mendis322591c2009-10-29 11:06:59 -07006806 boolean screenIsOff = !mPowerManager.isScreenOn();
6807 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 if (screenIsOff) {
6809 if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
6810 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006811 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 return false;
6813 }
6814 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6815 }
6816 if (screenIsDim) {
6817 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6818 }
6819 return true;
6820 }
Romain Guy06882f82009-06-10 13:36:04 -07006821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 default:
6823 return true;
6824 }
6825 }
6826
6827 public int filterEvent(QueuedEvent ev) {
6828 switch (ev.classType) {
6829 case RawInputEvent.CLASS_KEYBOARD:
6830 KeyEvent ke = (KeyEvent)ev.event;
6831 if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006832 Slog.w(TAG, "Dropping movement key during app switch: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 + ke.getKeyCode() + ", action=" + ke.getAction());
6834 return FILTER_REMOVE;
6835 }
6836 return FILTER_ABORT;
6837 default:
6838 return FILTER_KEEP;
6839 }
6840 }
Michael Chan53071d62009-05-13 17:29:48 -07006841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842
6843 public boolean detectSafeMode() {
6844 mSafeMode = mPolicy.detectSafeMode();
6845 return mSafeMode;
6846 }
Romain Guy06882f82009-06-10 13:36:04 -07006847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 public void systemReady() {
6849 mPolicy.systemReady();
6850 }
Romain Guy06882f82009-06-10 13:36:04 -07006851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006852 private final class InputDispatcherThread extends Thread {
6853 // Time to wait when there is nothing to do: 9999 seconds.
6854 static final int LONG_WAIT=9999*1000;
6855
6856 public InputDispatcherThread() {
6857 super("InputDispatcher");
6858 }
Romain Guy06882f82009-06-10 13:36:04 -07006859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006860 @Override
6861 public void run() {
6862 while (true) {
6863 try {
6864 process();
6865 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006866 Slog.e(TAG, "Exception in input dispatcher", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 }
6868 }
6869 }
Romain Guy06882f82009-06-10 13:36:04 -07006870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 private void process() {
6872 android.os.Process.setThreadPriority(
6873 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -07006874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 // The last key event we saw
6876 KeyEvent lastKey = null;
6877
6878 // Last keydown time for auto-repeating keys
6879 long lastKeyTime = SystemClock.uptimeMillis();
6880 long nextKeyTime = lastKeyTime+LONG_WAIT;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006881 long downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882
Romain Guy06882f82009-06-10 13:36:04 -07006883 // How many successive repeats we generated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006884 int keyRepeatCount = 0;
6885
6886 // Need to report that configuration has changed?
6887 boolean configChanged = false;
Romain Guy06882f82009-06-10 13:36:04 -07006888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 while (true) {
6890 long curTime = SystemClock.uptimeMillis();
6891
Joe Onorato8a9b2202010-02-26 18:56:32 -08006892 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006893 TAG, "Waiting for next key: now=" + curTime
6894 + ", repeat @ " + nextKeyTime);
6895
6896 // Retrieve next event, waiting only as long as the next
6897 // repeat timeout. If the configuration has changed, then
6898 // don't wait at all -- we'll report the change as soon as
6899 // we have processed all events.
6900 QueuedEvent ev = mQueue.getEvent(
6901 (int)((!configChanged && curTime < nextKeyTime)
6902 ? (nextKeyTime-curTime) : 0));
6903
Joe Onorato8a9b2202010-02-26 18:56:32 -08006904 if (DEBUG_INPUT && ev != null) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006905 TAG, "Event: type=" + ev.classType + " data=" + ev.event);
6906
Michael Chan53071d62009-05-13 17:29:48 -07006907 if (MEASURE_LATENCY) {
6908 lt.sample("2 got event ", System.nanoTime() - ev.whenNano);
6909 }
6910
Mike Lockwood3d0ea722009-10-21 22:58:29 -04006911 if (lastKey != null && !mPolicy.allowKeyRepeat()) {
6912 // cancel key repeat at the request of the policy.
6913 lastKey = null;
6914 downTime = 0;
6915 lastKeyTime = curTime;
6916 nextKeyTime = curTime + LONG_WAIT;
6917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 try {
6919 if (ev != null) {
Michael Chan53071d62009-05-13 17:29:48 -07006920 curTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006921 int eventType;
6922 if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
6923 eventType = eventType((MotionEvent)ev.event);
6924 } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
6925 ev.classType == RawInputEvent.CLASS_TRACKBALL) {
6926 eventType = LocalPowerManager.BUTTON_EVENT;
6927 } else {
6928 eventType = LocalPowerManager.OTHER_EVENT;
6929 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006930 try {
Michael Chan53071d62009-05-13 17:29:48 -07006931 if ((curTime - mLastBatteryStatsCallTime)
Michael Chane96440f2009-05-06 10:27:36 -07006932 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
Michael Chan53071d62009-05-13 17:29:48 -07006933 mLastBatteryStatsCallTime = curTime;
Michael Chane96440f2009-05-06 10:27:36 -07006934 mBatteryStats.noteInputEvent();
6935 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006936 } catch (RemoteException e) {
6937 // Ignore
6938 }
Michael Chane10de972009-05-18 11:24:50 -07006939
Mike Lockwood5db42402009-11-30 14:51:51 -05006940 if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
6941 // do not wake screen in this case
6942 } else if (eventType != TOUCH_EVENT
Michael Chane10de972009-05-18 11:24:50 -07006943 && eventType != LONG_TOUCH_EVENT
6944 && eventType != CHEEK_EVENT) {
6945 mPowerManager.userActivity(curTime, false,
6946 eventType, false);
6947 } else if (mLastTouchEventType != eventType
6948 || (curTime - mLastUserActivityCallTime)
6949 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
6950 mLastUserActivityCallTime = curTime;
6951 mLastTouchEventType = eventType;
6952 mPowerManager.userActivity(curTime, false,
6953 eventType, false);
6954 }
6955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 switch (ev.classType) {
6957 case RawInputEvent.CLASS_KEYBOARD:
6958 KeyEvent ke = (KeyEvent)ev.event;
6959 if (ke.isDown()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006960 lastKeyTime = curTime;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006961 if (lastKey != null &&
6962 ke.getKeyCode() == lastKey.getKeyCode()) {
6963 keyRepeatCount++;
6964 // Arbitrary long timeout to block
6965 // repeating here since we know that
6966 // the device driver takes care of it.
6967 nextKeyTime = lastKeyTime + LONG_WAIT;
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07006968 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006969 TAG, "Received repeated key down");
6970 } else {
6971 downTime = curTime;
6972 keyRepeatCount = 0;
6973 nextKeyTime = lastKeyTime
6974 + ViewConfiguration.getLongPressTimeout();
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07006975 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006976 TAG, "Received key down: first repeat @ "
6977 + nextKeyTime);
6978 }
6979 lastKey = ke;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 } else {
6981 lastKey = null;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006982 downTime = 0;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006983 keyRepeatCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 // Arbitrary long timeout.
6985 lastKeyTime = curTime;
6986 nextKeyTime = curTime + LONG_WAIT;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006987 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 TAG, "Received key up: ignore repeat @ "
6989 + nextKeyTime);
6990 }
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006991 if (keyRepeatCount > 0) {
6992 dispatchKey(KeyEvent.changeTimeRepeat(ke,
6993 ke.getEventTime(), keyRepeatCount), 0, 0);
6994 } else {
6995 dispatchKey(ke, 0, 0);
6996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006997 mQueue.recycleEvent(ev);
6998 break;
6999 case RawInputEvent.CLASS_TOUCHSCREEN:
Joe Onorato8a9b2202010-02-26 18:56:32 -08007000 //Slog.i(TAG, "Read next event " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007001 dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
7002 break;
7003 case RawInputEvent.CLASS_TRACKBALL:
7004 dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
7005 break;
7006 case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
7007 configChanged = true;
7008 break;
7009 default:
7010 mQueue.recycleEvent(ev);
7011 break;
7012 }
Romain Guy06882f82009-06-10 13:36:04 -07007013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007014 } else if (configChanged) {
7015 configChanged = false;
7016 sendNewConfiguration();
Romain Guy06882f82009-06-10 13:36:04 -07007017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 } else if (lastKey != null) {
7019 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 // Timeout occurred while key was down. If it is at or
7022 // past the key repeat time, dispatch the repeat.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007023 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 TAG, "Key timeout: repeat=" + nextKeyTime
7025 + ", now=" + curTime);
7026 if (curTime < nextKeyTime) {
7027 continue;
7028 }
Romain Guy06882f82009-06-10 13:36:04 -07007029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 lastKeyTime = nextKeyTime;
7031 nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
7032 keyRepeatCount++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007033 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034 TAG, "Key repeat: count=" + keyRepeatCount
7035 + ", next @ " + nextKeyTime);
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007036 KeyEvent newEvent;
7037 if (downTime != 0 && (downTime
7038 + ViewConfiguration.getLongPressTimeout())
7039 <= curTime) {
7040 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7041 curTime, keyRepeatCount,
7042 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
7043 downTime = 0;
7044 } else {
7045 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7046 curTime, keyRepeatCount);
7047 }
7048 dispatchKey(newEvent, 0, 0);
Romain Guy06882f82009-06-10 13:36:04 -07007049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 } else {
7051 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 lastKeyTime = curTime;
7054 nextKeyTime = curTime + LONG_WAIT;
7055 }
Romain Guy06882f82009-06-10 13:36:04 -07007056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007058 Slog.e(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 "Input thread received uncaught exception: " + e, e);
7060 }
7061 }
7062 }
7063 }
7064
7065 // -------------------------------------------------------------
7066 // Client Session State
7067 // -------------------------------------------------------------
7068
7069 private final class Session extends IWindowSession.Stub
7070 implements IBinder.DeathRecipient {
7071 final IInputMethodClient mClient;
7072 final IInputContext mInputContext;
7073 final int mUid;
7074 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007075 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 SurfaceSession mSurfaceSession;
7077 int mNumWindow = 0;
7078 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07007079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007080 /**
7081 * Current pointer move event being dispatched to client window... must
7082 * hold key lock to access.
7083 */
7084 QueuedEvent mPendingPointerMove;
7085 WindowState mPendingPointerWindow;
Romain Guy06882f82009-06-10 13:36:04 -07007086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 /**
7088 * Current trackball move event being dispatched to client window... must
7089 * hold key lock to access.
7090 */
7091 QueuedEvent mPendingTrackballMove;
7092 WindowState mPendingTrackballWindow;
7093
7094 public Session(IInputMethodClient client, IInputContext inputContext) {
7095 mClient = client;
7096 mInputContext = inputContext;
7097 mUid = Binder.getCallingUid();
7098 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007099 StringBuilder sb = new StringBuilder();
7100 sb.append("Session{");
7101 sb.append(Integer.toHexString(System.identityHashCode(this)));
7102 sb.append(" uid ");
7103 sb.append(mUid);
7104 sb.append("}");
7105 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07007106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 synchronized (mWindowMap) {
7108 if (mInputMethodManager == null && mHaveInputMethods) {
7109 IBinder b = ServiceManager.getService(
7110 Context.INPUT_METHOD_SERVICE);
7111 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
7112 }
7113 }
7114 long ident = Binder.clearCallingIdentity();
7115 try {
7116 // Note: it is safe to call in to the input method manager
7117 // here because we are not holding our lock.
7118 if (mInputMethodManager != null) {
7119 mInputMethodManager.addClient(client, inputContext,
7120 mUid, mPid);
7121 } else {
7122 client.setUsingInputMethod(false);
7123 }
7124 client.asBinder().linkToDeath(this, 0);
7125 } catch (RemoteException e) {
7126 // The caller has died, so we can just forget about this.
7127 try {
7128 if (mInputMethodManager != null) {
7129 mInputMethodManager.removeClient(client);
7130 }
7131 } catch (RemoteException ee) {
7132 }
7133 } finally {
7134 Binder.restoreCallingIdentity(ident);
7135 }
7136 }
Romain Guy06882f82009-06-10 13:36:04 -07007137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 @Override
7139 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
7140 throws RemoteException {
7141 try {
7142 return super.onTransact(code, data, reply, flags);
7143 } catch (RuntimeException e) {
7144 // Log all 'real' exceptions thrown to the caller
7145 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007146 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007147 }
7148 throw e;
7149 }
7150 }
7151
7152 public void binderDied() {
7153 // Note: it is safe to call in to the input method manager
7154 // here because we are not holding our lock.
7155 try {
7156 if (mInputMethodManager != null) {
7157 mInputMethodManager.removeClient(mClient);
7158 }
7159 } catch (RemoteException e) {
7160 }
7161 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07007162 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 mClientDead = true;
7164 killSessionLocked();
7165 }
7166 }
7167
7168 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007169 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
7170 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
7171 outInputChannel);
7172 }
7173
7174 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007175 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007176 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007177 }
Romain Guy06882f82009-06-10 13:36:04 -07007178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007179 public void remove(IWindow window) {
7180 removeWindow(this, window);
7181 }
Romain Guy06882f82009-06-10 13:36:04 -07007182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
7184 int requestedWidth, int requestedHeight, int viewFlags,
7185 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007186 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 return relayoutWindow(this, window, attrs,
7188 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007189 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007190 }
Romain Guy06882f82009-06-10 13:36:04 -07007191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 public void setTransparentRegion(IWindow window, Region region) {
7193 setTransparentRegionWindow(this, window, region);
7194 }
Romain Guy06882f82009-06-10 13:36:04 -07007195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 public void setInsets(IWindow window, int touchableInsets,
7197 Rect contentInsets, Rect visibleInsets) {
7198 setInsetsWindow(this, window, touchableInsets, contentInsets,
7199 visibleInsets);
7200 }
Romain Guy06882f82009-06-10 13:36:04 -07007201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
7203 getWindowDisplayFrame(this, window, outDisplayFrame);
7204 }
Romain Guy06882f82009-06-10 13:36:04 -07007205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007207 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007208 TAG, "IWindow finishDrawing called for " + window);
7209 finishDrawingWindow(this, window);
7210 }
7211
7212 public void finishKey(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007213 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 TAG, "IWindow finishKey called for " + window);
7215 mKeyWaiter.finishedKey(this, window, false,
7216 KeyWaiter.RETURN_NOTHING);
7217 }
7218
7219 public MotionEvent getPendingPointerMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007220 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007221 TAG, "IWindow getPendingMotionEvent called for " + window);
7222 return mKeyWaiter.finishedKey(this, window, false,
7223 KeyWaiter.RETURN_PENDING_POINTER);
7224 }
Romain Guy06882f82009-06-10 13:36:04 -07007225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 public MotionEvent getPendingTrackballMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007227 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 TAG, "IWindow getPendingMotionEvent called for " + window);
7229 return mKeyWaiter.finishedKey(this, window, false,
7230 KeyWaiter.RETURN_PENDING_TRACKBALL);
7231 }
7232
7233 public void setInTouchMode(boolean mode) {
7234 synchronized(mWindowMap) {
7235 mInTouchMode = mode;
7236 }
7237 }
7238
7239 public boolean getInTouchMode() {
7240 synchronized(mWindowMap) {
7241 return mInTouchMode;
7242 }
7243 }
7244
7245 public boolean performHapticFeedback(IWindow window, int effectId,
7246 boolean always) {
7247 synchronized(mWindowMap) {
7248 long ident = Binder.clearCallingIdentity();
7249 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007250 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007251 windowForClientLocked(this, window, true),
7252 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 } finally {
7254 Binder.restoreCallingIdentity(ident);
7255 }
7256 }
7257 }
Romain Guy06882f82009-06-10 13:36:04 -07007258
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007259 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007260 synchronized(mWindowMap) {
7261 long ident = Binder.clearCallingIdentity();
7262 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007263 setWindowWallpaperPositionLocked(
7264 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007265 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007266 } finally {
7267 Binder.restoreCallingIdentity(ident);
7268 }
7269 }
7270 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007271
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007272 public void wallpaperOffsetsComplete(IBinder window) {
7273 WindowManagerService.this.wallpaperOffsetsComplete(window);
7274 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007275
Dianne Hackborn75804932009-10-20 20:15:20 -07007276 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
7277 int z, Bundle extras, boolean sync) {
7278 synchronized(mWindowMap) {
7279 long ident = Binder.clearCallingIdentity();
7280 try {
7281 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007282 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07007283 action, x, y, z, extras, sync);
7284 } finally {
7285 Binder.restoreCallingIdentity(ident);
7286 }
7287 }
7288 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007289
Dianne Hackborn75804932009-10-20 20:15:20 -07007290 public void wallpaperCommandComplete(IBinder window, Bundle result) {
7291 WindowManagerService.this.wallpaperCommandComplete(window, result);
7292 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007294 void windowAddedLocked() {
7295 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007296 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007297 TAG, "First window added to " + this + ", creating SurfaceSession");
7298 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007299 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007300 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007301 mSessions.add(this);
7302 }
7303 mNumWindow++;
7304 }
7305
7306 void windowRemovedLocked() {
7307 mNumWindow--;
7308 killSessionLocked();
7309 }
Romain Guy06882f82009-06-10 13:36:04 -07007310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 void killSessionLocked() {
7312 if (mNumWindow <= 0 && mClientDead) {
7313 mSessions.remove(this);
7314 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007315 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007316 TAG, "Last window removed from " + this
7317 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007318 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007319 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007320 try {
7321 mSurfaceSession.kill();
7322 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007323 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007324 + mSurfaceSession + " in session " + this
7325 + ": " + e.toString());
7326 }
7327 mSurfaceSession = null;
7328 }
7329 }
7330 }
Romain Guy06882f82009-06-10 13:36:04 -07007331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007333 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
7334 pw.print(" mClientDead="); pw.print(mClientDead);
7335 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
7336 if (mPendingPointerWindow != null || mPendingPointerMove != null) {
7337 pw.print(prefix);
7338 pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
7339 pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
7340 }
7341 if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
7342 pw.print(prefix);
7343 pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
7344 pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
7345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007346 }
7347
7348 @Override
7349 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007350 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007351 }
7352 }
7353
7354 // -------------------------------------------------------------
7355 // Client Window State
7356 // -------------------------------------------------------------
7357
7358 private final class WindowState implements WindowManagerPolicy.WindowState {
7359 final Session mSession;
7360 final IWindow mClient;
7361 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07007362 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 AppWindowToken mAppToken;
7364 AppWindowToken mTargetAppToken;
7365 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
7366 final DeathRecipient mDeathRecipient;
7367 final WindowState mAttachedWindow;
7368 final ArrayList mChildWindows = new ArrayList();
7369 final int mBaseLayer;
7370 final int mSubLayer;
7371 final boolean mLayoutAttached;
7372 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007373 final boolean mIsWallpaper;
7374 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 int mViewVisibility;
7376 boolean mPolicyVisibility = true;
7377 boolean mPolicyVisibilityAfterAnim = true;
7378 boolean mAppFreezing;
7379 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007380 boolean mReportDestroySurface;
7381 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 boolean mAttachedHidden; // is our parent window hidden?
7383 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007384 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 int mRequestedWidth;
7386 int mRequestedHeight;
7387 int mLastRequestedWidth;
7388 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 int mLayer;
7390 int mAnimLayer;
7391 int mLastLayer;
7392 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007393 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007394 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007395
7396 WindowState mNextOutsideTouch;
Romain Guy06882f82009-06-10 13:36:04 -07007397
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007398 int mLayoutSeq = -1;
7399
7400 Configuration mConfiguration = null;
7401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 // Actual frame shown on-screen (may be modified by animation)
7403 final Rect mShownFrame = new Rect();
7404 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007407 * Set when we have changed the size of the surface, to know that
7408 * we must tell them application to resize (and thus redraw itself).
7409 */
7410 boolean mSurfaceResized;
7411
7412 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007413 * Insets that determine the actually visible area
7414 */
7415 final Rect mVisibleInsets = new Rect();
7416 final Rect mLastVisibleInsets = new Rect();
7417 boolean mVisibleInsetsChanged;
7418
7419 /**
7420 * Insets that are covered by system windows
7421 */
7422 final Rect mContentInsets = new Rect();
7423 final Rect mLastContentInsets = new Rect();
7424 boolean mContentInsetsChanged;
7425
7426 /**
7427 * Set to true if we are waiting for this window to receive its
7428 * given internal insets before laying out other windows based on it.
7429 */
7430 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07007431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 /**
7433 * These are the content insets that were given during layout for
7434 * this window, to be applied to windows behind it.
7435 */
7436 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007438 /**
7439 * These are the visible insets that were given during layout for
7440 * this window, to be applied to windows behind it.
7441 */
7442 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 /**
7445 * Flag indicating whether the touchable region should be adjusted by
7446 * the visible insets; if false the area outside the visible insets is
7447 * NOT touchable, so we must use those to adjust the frame during hit
7448 * tests.
7449 */
7450 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07007451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 // Current transformation being applied.
7453 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
7454 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
7455 float mHScale=1, mVScale=1;
7456 float mLastHScale=1, mLastVScale=1;
7457 final Matrix mTmpMatrix = new Matrix();
7458
7459 // "Real" frame that the application sees.
7460 final Rect mFrame = new Rect();
7461 final Rect mLastFrame = new Rect();
7462
7463 final Rect mContainingFrame = new Rect();
7464 final Rect mDisplayFrame = new Rect();
7465 final Rect mContentFrame = new Rect();
7466 final Rect mVisibleFrame = new Rect();
7467
7468 float mShownAlpha = 1;
7469 float mAlpha = 1;
7470 float mLastAlpha = 1;
7471
7472 // Set to true if, when the window gets displayed, it should perform
7473 // an enter animation.
7474 boolean mEnterAnimationPending;
7475
7476 // Currently running animation.
7477 boolean mAnimating;
7478 boolean mLocalAnimating;
7479 Animation mAnimation;
7480 boolean mAnimationIsEntrance;
7481 boolean mHasTransformation;
7482 boolean mHasLocalTransformation;
7483 final Transformation mTransformation = new Transformation();
7484
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007485 // If a window showing a wallpaper: the requested offset for the
7486 // wallpaper; if a wallpaper window: the currently applied offset.
7487 float mWallpaperX = -1;
7488 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007489
7490 // If a window showing a wallpaper: what fraction of the offset
7491 // range corresponds to a full virtual screen.
7492 float mWallpaperXStep = -1;
7493 float mWallpaperYStep = -1;
7494
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007495 // Wallpaper windows: pixels offset based on above variables.
7496 int mXOffset;
7497 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007499 // This is set after IWindowSession.relayout() has been called at
7500 // least once for the window. It allows us to detect the situation
7501 // where we don't yet have a surface, but should have one soon, so
7502 // we can give the window focus before waiting for the relayout.
7503 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007505 // This is set after the Surface has been created but before the
7506 // window has been drawn. During this time the surface is hidden.
7507 boolean mDrawPending;
7508
7509 // This is set after the window has finished drawing for the first
7510 // time but before its surface is shown. The surface will be
7511 // displayed when the next layout is run.
7512 boolean mCommitDrawPending;
7513
7514 // This is set during the time after the window's drawing has been
7515 // committed, and before its surface is actually shown. It is used
7516 // to delay showing the surface until all windows in a token are ready
7517 // to be shown.
7518 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007520 // Set when the window has been shown in the screen the first time.
7521 boolean mHasDrawn;
7522
7523 // Currently running an exit animation?
7524 boolean mExiting;
7525
7526 // Currently on the mDestroySurface list?
7527 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007529 // Completely remove from window manager after exit animation?
7530 boolean mRemoveOnExit;
7531
7532 // Set when the orientation is changing and this window has not yet
7533 // been updated for the new orientation.
7534 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 // Is this window now (or just being) removed?
7537 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007538
Dianne Hackborn16064f92010-03-25 00:47:24 -07007539 // For debugging, this is the last information given to the surface flinger.
7540 boolean mSurfaceShown;
7541 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7542 int mSurfaceLayer;
7543 float mSurfaceAlpha;
7544
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007545 // Input channel
7546 InputChannel mInputChannel;
7547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 WindowState(Session s, IWindow c, WindowToken token,
7549 WindowState attachedWindow, WindowManager.LayoutParams a,
7550 int viewVisibility) {
7551 mSession = s;
7552 mClient = c;
7553 mToken = token;
7554 mAttrs.copyFrom(a);
7555 mViewVisibility = viewVisibility;
7556 DeathRecipient deathRecipient = new DeathRecipient();
7557 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007558 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 TAG, "Window " + this + " client=" + c.asBinder()
7560 + " token=" + token + " (" + mAttrs.token + ")");
7561 try {
7562 c.asBinder().linkToDeath(deathRecipient, 0);
7563 } catch (RemoteException e) {
7564 mDeathRecipient = null;
7565 mAttachedWindow = null;
7566 mLayoutAttached = false;
7567 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007568 mIsWallpaper = false;
7569 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007570 mBaseLayer = 0;
7571 mSubLayer = 0;
7572 return;
7573 }
7574 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007576 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7577 mAttrs.type <= LAST_SUB_WINDOW)) {
7578 // The multiplier here is to reserve space for multiple
7579 // windows in the same type layer.
7580 mBaseLayer = mPolicy.windowTypeToLayerLw(
7581 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7582 + TYPE_LAYER_OFFSET;
7583 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7584 mAttachedWindow = attachedWindow;
7585 mAttachedWindow.mChildWindows.add(this);
7586 mLayoutAttached = mAttrs.type !=
7587 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7588 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7589 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007590 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7591 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007592 } else {
7593 // The multiplier here is to reserve space for multiple
7594 // windows in the same type layer.
7595 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7596 * TYPE_LAYER_MULTIPLIER
7597 + TYPE_LAYER_OFFSET;
7598 mSubLayer = 0;
7599 mAttachedWindow = null;
7600 mLayoutAttached = false;
7601 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7602 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007603 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7604 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007605 }
7606
7607 WindowState appWin = this;
7608 while (appWin.mAttachedWindow != null) {
7609 appWin = mAttachedWindow;
7610 }
7611 WindowToken appToken = appWin.mToken;
7612 while (appToken.appWindowToken == null) {
7613 WindowToken parent = mTokenMap.get(appToken.token);
7614 if (parent == null || appToken == parent) {
7615 break;
7616 }
7617 appToken = parent;
7618 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007619 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620 mAppToken = appToken.appWindowToken;
7621
7622 mSurface = null;
7623 mRequestedWidth = 0;
7624 mRequestedHeight = 0;
7625 mLastRequestedWidth = 0;
7626 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007627 mXOffset = 0;
7628 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 mLayer = 0;
7630 mAnimLayer = 0;
7631 mLastLayer = 0;
7632 }
7633
7634 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007635 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007636 TAG, "Attaching " + this + " token=" + mToken
7637 + ", list=" + mToken.windows);
7638 mSession.windowAddedLocked();
7639 }
7640
7641 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7642 mHaveFrame = true;
7643
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007644 final Rect container = mContainingFrame;
7645 container.set(pf);
7646
7647 final Rect display = mDisplayFrame;
7648 display.set(df);
7649
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007650 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007651 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007652 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7653 display.intersect(mCompatibleScreenFrame);
7654 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007655 }
7656
7657 final int pw = container.right - container.left;
7658 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659
7660 int w,h;
7661 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7662 w = mAttrs.width < 0 ? pw : mAttrs.width;
7663 h = mAttrs.height< 0 ? ph : mAttrs.height;
7664 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007665 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7666 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007667 }
Romain Guy06882f82009-06-10 13:36:04 -07007668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 final Rect content = mContentFrame;
7670 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 final Rect visible = mVisibleFrame;
7673 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007675 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007676 final int fw = frame.width();
7677 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007679 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7680 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7681
7682 Gravity.apply(mAttrs.gravity, w, h, container,
7683 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7684 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7685
7686 //System.out.println("Out: " + mFrame);
7687
7688 // Now make sure the window fits in the overall display.
7689 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 // Make sure the content and visible frames are inside of the
7692 // final window frame.
7693 if (content.left < frame.left) content.left = frame.left;
7694 if (content.top < frame.top) content.top = frame.top;
7695 if (content.right > frame.right) content.right = frame.right;
7696 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7697 if (visible.left < frame.left) visible.left = frame.left;
7698 if (visible.top < frame.top) visible.top = frame.top;
7699 if (visible.right > frame.right) visible.right = frame.right;
7700 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 final Rect contentInsets = mContentInsets;
7703 contentInsets.left = content.left-frame.left;
7704 contentInsets.top = content.top-frame.top;
7705 contentInsets.right = frame.right-content.right;
7706 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007708 final Rect visibleInsets = mVisibleInsets;
7709 visibleInsets.left = visible.left-frame.left;
7710 visibleInsets.top = visible.top-frame.top;
7711 visibleInsets.right = frame.right-visible.right;
7712 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007713
Dianne Hackborn284ac932009-08-28 10:34:25 -07007714 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7715 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007716 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007717 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007719 if (localLOGV) {
7720 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7721 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007722 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007723 + mRequestedWidth + ", mRequestedheight="
7724 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7725 + "): frame=" + mFrame.toShortString()
7726 + " ci=" + contentInsets.toShortString()
7727 + " vi=" + visibleInsets.toShortString());
7728 //}
7729 }
7730 }
Romain Guy06882f82009-06-10 13:36:04 -07007731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732 public Rect getFrameLw() {
7733 return mFrame;
7734 }
7735
7736 public Rect getShownFrameLw() {
7737 return mShownFrame;
7738 }
7739
7740 public Rect getDisplayFrameLw() {
7741 return mDisplayFrame;
7742 }
7743
7744 public Rect getContentFrameLw() {
7745 return mContentFrame;
7746 }
7747
7748 public Rect getVisibleFrameLw() {
7749 return mVisibleFrame;
7750 }
7751
7752 public boolean getGivenInsetsPendingLw() {
7753 return mGivenInsetsPending;
7754 }
7755
7756 public Rect getGivenContentInsetsLw() {
7757 return mGivenContentInsets;
7758 }
Romain Guy06882f82009-06-10 13:36:04 -07007759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007760 public Rect getGivenVisibleInsetsLw() {
7761 return mGivenVisibleInsets;
7762 }
Romain Guy06882f82009-06-10 13:36:04 -07007763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 public WindowManager.LayoutParams getAttrs() {
7765 return mAttrs;
7766 }
7767
7768 public int getSurfaceLayer() {
7769 return mLayer;
7770 }
Romain Guy06882f82009-06-10 13:36:04 -07007771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 public IApplicationToken getAppToken() {
7773 return mAppToken != null ? mAppToken.appToken : null;
7774 }
7775
7776 public boolean hasAppShownWindows() {
7777 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7778 }
7779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007780 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007781 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 TAG, "Setting animation in " + this + ": " + anim);
7783 mAnimating = false;
7784 mLocalAnimating = false;
7785 mAnimation = anim;
7786 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7787 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7788 }
7789
7790 public void clearAnimation() {
7791 if (mAnimation != null) {
7792 mAnimating = true;
7793 mLocalAnimating = false;
7794 mAnimation = null;
7795 }
7796 }
Romain Guy06882f82009-06-10 13:36:04 -07007797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007798 Surface createSurfaceLocked() {
7799 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007800 mReportDestroySurface = false;
7801 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 mDrawPending = true;
7803 mCommitDrawPending = false;
7804 mReadyToShow = false;
7805 if (mAppToken != null) {
7806 mAppToken.allDrawn = false;
7807 }
7808
7809 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07007810 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 flags |= Surface.PUSH_BUFFERS;
7812 }
7813
7814 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7815 flags |= Surface.SECURE;
7816 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007817 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007818 TAG, "Creating surface in session "
7819 + mSession.mSurfaceSession + " window " + this
7820 + " w=" + mFrame.width()
7821 + " h=" + mFrame.height() + " format="
7822 + mAttrs.format + " flags=" + flags);
7823
7824 int w = mFrame.width();
7825 int h = mFrame.height();
7826 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7827 // for a scaled surface, we always want the requested
7828 // size.
7829 w = mRequestedWidth;
7830 h = mRequestedHeight;
7831 }
7832
Romain Guy9825ec62009-10-01 00:58:09 -07007833 // Something is wrong and SurfaceFlinger will not like this,
7834 // try to revert to sane values
7835 if (w <= 0) w = 1;
7836 if (h <= 0) h = 1;
7837
Dianne Hackborn16064f92010-03-25 00:47:24 -07007838 mSurfaceShown = false;
7839 mSurfaceLayer = 0;
7840 mSurfaceAlpha = 1;
7841 mSurfaceX = 0;
7842 mSurfaceY = 0;
7843 mSurfaceW = w;
7844 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007845 try {
7846 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007847 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007848 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007850 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007851 + mSurface + " IN SESSION "
7852 + mSession.mSurfaceSession
7853 + ": pid=" + mSession.mPid + " format="
7854 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007855 + Integer.toHexString(flags)
7856 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007858 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 reclaimSomeSurfaceMemoryLocked(this, "create");
7860 return null;
7861 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007862 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007863 return null;
7864 }
Romain Guy06882f82009-06-10 13:36:04 -07007865
Joe Onorato8a9b2202010-02-26 18:56:32 -08007866 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 TAG, "Got surface: " + mSurface
7868 + ", set left=" + mFrame.left + " top=" + mFrame.top
7869 + ", animLayer=" + mAnimLayer);
7870 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007871 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007872 if (SHOW_TRANSACTIONS) logSurface(this,
7873 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7874 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7875 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 }
7877 Surface.openTransaction();
7878 try {
7879 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007880 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007881 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007882 mSurface.setPosition(mSurfaceX, mSurfaceY);
7883 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007884 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007885 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007886 mSurface.hide();
7887 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007888 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007889 mSurface.setFlags(Surface.SURFACE_DITHER,
7890 Surface.SURFACE_DITHER);
7891 }
7892 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007893 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7895 }
7896 mLastHidden = true;
7897 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007898 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007899 Surface.closeTransaction();
7900 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007901 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007902 TAG, "Created surface " + this);
7903 }
7904 return mSurface;
7905 }
Romain Guy06882f82009-06-10 13:36:04 -07007906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907 void destroySurfaceLocked() {
7908 // Window is no longer on-screen, so can no longer receive
7909 // key events... if we were waiting for it to finish
7910 // handling a key event, the wait is over!
7911 mKeyWaiter.finishedKey(mSession, mClient, true,
7912 KeyWaiter.RETURN_NOTHING);
7913 mKeyWaiter.releasePendingPointerLocked(mSession);
7914 mKeyWaiter.releasePendingTrackballLocked(mSession);
7915
7916 if (mAppToken != null && this == mAppToken.startingWindow) {
7917 mAppToken.startingDisplayed = false;
7918 }
Romain Guy06882f82009-06-10 13:36:04 -07007919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007920 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007921 mDrawPending = false;
7922 mCommitDrawPending = false;
7923 mReadyToShow = false;
7924
7925 int i = mChildWindows.size();
7926 while (i > 0) {
7927 i--;
7928 WindowState c = (WindowState)mChildWindows.get(i);
7929 c.mAttachedHidden = true;
7930 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007931
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007932 if (mReportDestroySurface) {
7933 mReportDestroySurface = false;
7934 mSurfacePendingDestroy = true;
7935 try {
7936 mClient.dispatchGetNewSurface();
7937 // We'll really destroy on the next time around.
7938 return;
7939 } catch (RemoteException e) {
7940 }
7941 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007944 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007945 RuntimeException e = null;
7946 if (!HIDE_STACK_CRAWLS) {
7947 e = new RuntimeException();
7948 e.fillInStackTrace();
7949 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007950 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007951 + mSurface + ", session " + mSession, e);
7952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007954 RuntimeException e = null;
7955 if (!HIDE_STACK_CRAWLS) {
7956 e = new RuntimeException();
7957 e.fillInStackTrace();
7958 }
7959 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007960 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007961 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007963 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964 + " surface " + mSurface + " session " + mSession
7965 + ": " + e.toString());
7966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007967
Dianne Hackborn16064f92010-03-25 00:47:24 -07007968 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 }
7971 }
7972
7973 boolean finishDrawingLocked() {
7974 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007975 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007976 TAG, "finishDrawingLocked: " + mSurface);
7977 mCommitDrawPending = true;
7978 mDrawPending = false;
7979 return true;
7980 }
7981 return false;
7982 }
7983
7984 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007985 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007986 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007988 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 }
7990 mCommitDrawPending = false;
7991 mReadyToShow = true;
7992 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7993 final AppWindowToken atoken = mAppToken;
7994 if (atoken == null || atoken.allDrawn || starting) {
7995 performShowLocked();
7996 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007997 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007998 }
7999
8000 // This must be called while inside a transaction.
8001 boolean performShowLocked() {
8002 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008003 RuntimeException e = null;
8004 if (!HIDE_STACK_CRAWLS) {
8005 e = new RuntimeException();
8006 e.fillInStackTrace();
8007 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008008 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
8010 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
8011 }
8012 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008013 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
8014 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008015 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008016 + " during animation: policyVis=" + mPolicyVisibility
8017 + " attHidden=" + mAttachedHidden
8018 + " tok.hiddenRequested="
8019 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07008020 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008021 + (mAppToken != null ? mAppToken.hidden : false)
8022 + " animating=" + mAnimating
8023 + " tok animating="
8024 + (mAppToken != null ? mAppToken.animating : false));
8025 if (!showSurfaceRobustlyLocked(this)) {
8026 return false;
8027 }
8028 mLastAlpha = -1;
8029 mHasDrawn = true;
8030 mLastHidden = false;
8031 mReadyToShow = false;
8032 enableScreenIfNeededLocked();
8033
8034 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07008035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 int i = mChildWindows.size();
8037 while (i > 0) {
8038 i--;
8039 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008040 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008041 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008042 if (c.mSurface != null) {
8043 c.performShowLocked();
8044 // It hadn't been shown, which means layout not
8045 // performed on it, so now we want to make sure to
8046 // do a layout. If called from within the transaction
8047 // loop, this will cause it to restart with a new
8048 // layout.
8049 mLayoutNeeded = true;
8050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 }
8052 }
Romain Guy06882f82009-06-10 13:36:04 -07008053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008054 if (mAttrs.type != TYPE_APPLICATION_STARTING
8055 && mAppToken != null) {
8056 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008057
Dianne Hackborn248b1882009-09-16 16:46:44 -07008058 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008059 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008060 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07008062 // If this initial window is animating, stop it -- we
8063 // will do an animation to reveal it from behind the
8064 // starting window, so there is no need for it to also
8065 // be doing its own stuff.
8066 if (mAnimation != null) {
8067 mAnimation = null;
8068 // Make sure we clean up the animation.
8069 mAnimating = true;
8070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 mFinishedStarting.add(mAppToken);
8072 mH.sendEmptyMessage(H.FINISHED_STARTING);
8073 }
8074 mAppToken.updateReportedVisibilityLocked();
8075 }
8076 }
8077 return true;
8078 }
Romain Guy06882f82009-06-10 13:36:04 -07008079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 // This must be called while inside a transaction. Returns true if
8081 // there is more animation to run.
8082 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008083 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008084 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
8087 mHasTransformation = true;
8088 mHasLocalTransformation = true;
8089 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008090 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 TAG, "Starting animation in " + this +
8092 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
8093 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
8094 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
8095 mAnimation.setStartTime(currentTime);
8096 mLocalAnimating = true;
8097 mAnimating = true;
8098 }
8099 mTransformation.clear();
8100 final boolean more = mAnimation.getTransformation(
8101 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008102 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 TAG, "Stepped animation in " + this +
8104 ": more=" + more + ", xform=" + mTransformation);
8105 if (more) {
8106 // we're not done!
8107 return true;
8108 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008109 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 TAG, "Finished animation in " + this +
8111 " @ " + currentTime);
8112 mAnimation = null;
8113 //WindowManagerService.this.dump();
8114 }
8115 mHasLocalTransformation = false;
8116 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008117 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008118 // When our app token is animating, we kind-of pretend like
8119 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
8120 // part of this check means that we will only do this if
8121 // our window is not currently exiting, or it is not
8122 // locally animating itself. The idea being that one that
8123 // is exiting and doing a local animation should be removed
8124 // once that animation is done.
8125 mAnimating = true;
8126 mHasTransformation = true;
8127 mTransformation.clear();
8128 return false;
8129 } else if (mHasTransformation) {
8130 // Little trick to get through the path below to act like
8131 // we have finished an animation.
8132 mAnimating = true;
8133 } else if (isAnimating()) {
8134 mAnimating = true;
8135 }
8136 } else if (mAnimation != null) {
8137 // If the display is frozen, and there is a pending animation,
8138 // clear it and make sure we run the cleanup code.
8139 mAnimating = true;
8140 mLocalAnimating = true;
8141 mAnimation = null;
8142 }
Romain Guy06882f82009-06-10 13:36:04 -07008143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008144 if (!mAnimating && !mLocalAnimating) {
8145 return false;
8146 }
8147
Joe Onorato8a9b2202010-02-26 18:56:32 -08008148 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008149 TAG, "Animation done in " + this + ": exiting=" + mExiting
8150 + ", reportedVisible="
8151 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07008152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 mAnimating = false;
8154 mLocalAnimating = false;
8155 mAnimation = null;
8156 mAnimLayer = mLayer;
8157 if (mIsImWindow) {
8158 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008159 } else if (mIsWallpaper) {
8160 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008161 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008162 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 + " anim layer: " + mAnimLayer);
8164 mHasTransformation = false;
8165 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008166 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
8167 if (DEBUG_VISIBILITY) {
8168 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
8169 + mPolicyVisibilityAfterAnim);
8170 }
8171 mPolicyVisibility = mPolicyVisibilityAfterAnim;
8172 if (!mPolicyVisibility) {
8173 if (mCurrentFocus == this) {
8174 mFocusMayChange = true;
8175 }
8176 // Window is no longer visible -- make sure if we were waiting
8177 // for it to be displayed before enabling the display, that
8178 // we allow the display to be enabled now.
8179 enableScreenIfNeededLocked();
8180 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182 mTransformation.clear();
8183 if (mHasDrawn
8184 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
8185 && mAppToken != null
8186 && mAppToken.firstWindowDrawn
8187 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008188 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 + mToken + ": first real window done animating");
8190 mFinishedStarting.add(mAppToken);
8191 mH.sendEmptyMessage(H.FINISHED_STARTING);
8192 }
Romain Guy06882f82009-06-10 13:36:04 -07008193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 finishExit();
8195
8196 if (mAppToken != null) {
8197 mAppToken.updateReportedVisibilityLocked();
8198 }
8199
8200 return false;
8201 }
8202
8203 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008204 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008205 TAG, "finishExit in " + this
8206 + ": exiting=" + mExiting
8207 + " remove=" + mRemoveOnExit
8208 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07008209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210 final int N = mChildWindows.size();
8211 for (int i=0; i<N; i++) {
8212 ((WindowState)mChildWindows.get(i)).finishExit();
8213 }
Romain Guy06882f82009-06-10 13:36:04 -07008214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008215 if (!mExiting) {
8216 return;
8217 }
Romain Guy06882f82009-06-10 13:36:04 -07008218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 if (isWindowAnimating()) {
8220 return;
8221 }
8222
Joe Onorato8a9b2202010-02-26 18:56:32 -08008223 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008224 TAG, "Exit animation finished in " + this
8225 + ": remove=" + mRemoveOnExit);
8226 if (mSurface != null) {
8227 mDestroySurface.add(this);
8228 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008229 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008230 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008231 try {
8232 mSurface.hide();
8233 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008234 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008235 }
8236 mLastHidden = true;
8237 mKeyWaiter.releasePendingPointerLocked(mSession);
8238 }
8239 mExiting = false;
8240 if (mRemoveOnExit) {
8241 mPendingRemove.add(this);
8242 mRemoveOnExit = false;
8243 }
8244 }
Romain Guy06882f82009-06-10 13:36:04 -07008245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008246 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
8247 if (dsdx < .99999f || dsdx > 1.00001f) return false;
8248 if (dtdy < .99999f || dtdy > 1.00001f) return false;
8249 if (dtdx < -.000001f || dtdx > .000001f) return false;
8250 if (dsdy < -.000001f || dsdy > .000001f) return false;
8251 return true;
8252 }
Romain Guy06882f82009-06-10 13:36:04 -07008253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254 void computeShownFrameLocked() {
8255 final boolean selfTransformation = mHasLocalTransformation;
8256 Transformation attachedTransformation =
8257 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
8258 ? mAttachedWindow.mTransformation : null;
8259 Transformation appTransformation =
8260 (mAppToken != null && mAppToken.hasTransformation)
8261 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008262
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008263 // Wallpapers are animated based on the "real" window they
8264 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008265 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008266 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07008267 if (mWallpaperTarget.mHasLocalTransformation &&
8268 mWallpaperTarget.mAnimation != null &&
8269 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008270 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008271 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008272 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008273 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008274 }
8275 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07008276 mWallpaperTarget.mAppToken.hasTransformation &&
8277 mWallpaperTarget.mAppToken.animation != null &&
8278 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008279 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008280 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008281 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008282 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008283 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008284 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008286 if (selfTransformation || attachedTransformation != null
8287 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07008288 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289 final Rect frame = mFrame;
8290 final float tmpFloats[] = mTmpFloats;
8291 final Matrix tmpMatrix = mTmpMatrix;
8292
8293 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07008294 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008295 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008296 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008297 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07008298 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008300 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301 }
8302 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008303 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 }
8305
8306 // "convert" it into SurfaceFlinger's format
8307 // (a 2x2 matrix + an offset)
8308 // Here we must not transform the position of the surface
8309 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008310 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07008311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312 tmpMatrix.getValues(tmpFloats);
8313 mDsDx = tmpFloats[Matrix.MSCALE_X];
8314 mDtDx = tmpFloats[Matrix.MSKEW_X];
8315 mDsDy = tmpFloats[Matrix.MSKEW_Y];
8316 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008317 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
8318 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 int w = frame.width();
8320 int h = frame.height();
8321 mShownFrame.set(x, y, x+w, y+h);
8322
8323 // Now set the alpha... but because our current hardware
8324 // can't do alpha transformation on a non-opaque surface,
8325 // turn it off if we are running an animation that is also
8326 // transforming since it is more important to have that
8327 // animation be smooth.
8328 mShownAlpha = mAlpha;
8329 if (!mLimitedAlphaCompositing
8330 || (!PixelFormat.formatHasAlpha(mAttrs.format)
8331 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
8332 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008333 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 if (selfTransformation) {
8335 mShownAlpha *= mTransformation.getAlpha();
8336 }
8337 if (attachedTransformation != null) {
8338 mShownAlpha *= attachedTransformation.getAlpha();
8339 }
8340 if (appTransformation != null) {
8341 mShownAlpha *= appTransformation.getAlpha();
8342 }
8343 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008344 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008345 }
Romain Guy06882f82009-06-10 13:36:04 -07008346
Joe Onorato8a9b2202010-02-26 18:56:32 -08008347 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008348 TAG, "Continuing animation in " + this +
8349 ": " + mShownFrame +
8350 ", alpha=" + mTransformation.getAlpha());
8351 return;
8352 }
Romain Guy06882f82009-06-10 13:36:04 -07008353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008354 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008355 if (mXOffset != 0 || mYOffset != 0) {
8356 mShownFrame.offset(mXOffset, mYOffset);
8357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008358 mShownAlpha = mAlpha;
8359 mDsDx = 1;
8360 mDtDx = 0;
8361 mDsDy = 0;
8362 mDtDy = 1;
8363 }
Romain Guy06882f82009-06-10 13:36:04 -07008364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365 /**
8366 * Is this window visible? It is not visible if there is no
8367 * surface, or we are in the process of running an exit animation
8368 * that will remove the surface, or its app token has been hidden.
8369 */
8370 public boolean isVisibleLw() {
8371 final AppWindowToken atoken = mAppToken;
8372 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8373 && (atoken == null || !atoken.hiddenRequested)
8374 && !mExiting && !mDestroying;
8375 }
8376
8377 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008378 * Like {@link #isVisibleLw}, but also counts a window that is currently
8379 * "hidden" behind the keyguard as visible. This allows us to apply
8380 * things like window flags that impact the keyguard.
8381 * XXX I am starting to think we need to have ANOTHER visibility flag
8382 * for this "hidden behind keyguard" state rather than overloading
8383 * mPolicyVisibility. Ungh.
8384 */
8385 public boolean isVisibleOrBehindKeyguardLw() {
8386 final AppWindowToken atoken = mAppToken;
8387 return mSurface != null && !mAttachedHidden
8388 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008389 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008390 && !mExiting && !mDestroying;
8391 }
8392
8393 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008394 * Is this window visible, ignoring its app token? It is not visible
8395 * if there is no surface, or we are in the process of running an exit animation
8396 * that will remove the surface.
8397 */
8398 public boolean isWinVisibleLw() {
8399 final AppWindowToken atoken = mAppToken;
8400 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8401 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
8402 && !mExiting && !mDestroying;
8403 }
8404
8405 /**
8406 * The same as isVisible(), but follows the current hidden state of
8407 * the associated app token, not the pending requested hidden state.
8408 */
8409 boolean isVisibleNow() {
8410 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07008411 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412 }
8413
8414 /**
8415 * Same as isVisible(), but we also count it as visible between the
8416 * call to IWindowSession.add() and the first relayout().
8417 */
8418 boolean isVisibleOrAdding() {
8419 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008420 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
8422 && mPolicyVisibility && !mAttachedHidden
8423 && (atoken == null || !atoken.hiddenRequested)
8424 && !mExiting && !mDestroying;
8425 }
8426
8427 /**
8428 * Is this window currently on-screen? It is on-screen either if it
8429 * is visible or it is currently running an animation before no longer
8430 * being visible.
8431 */
8432 boolean isOnScreen() {
8433 final AppWindowToken atoken = mAppToken;
8434 if (atoken != null) {
8435 return mSurface != null && mPolicyVisibility && !mDestroying
8436 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008437 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 } else {
8439 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008440 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008441 }
8442 }
Romain Guy06882f82009-06-10 13:36:04 -07008443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008444 /**
8445 * Like isOnScreen(), but we don't return true if the window is part
8446 * of a transition that has not yet been started.
8447 */
8448 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008449 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008450 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008451 return false;
8452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008454 final boolean animating = atoken != null
8455 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008456 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008457 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8458 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008459 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 }
8461
8462 /** Is the window or its container currently animating? */
8463 boolean isAnimating() {
8464 final WindowState attached = mAttachedWindow;
8465 final AppWindowToken atoken = mAppToken;
8466 return mAnimation != null
8467 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008468 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469 (atoken.animation != null
8470 || atoken.inPendingTransaction));
8471 }
8472
8473 /** Is this window currently animating? */
8474 boolean isWindowAnimating() {
8475 return mAnimation != null;
8476 }
8477
8478 /**
8479 * Like isOnScreen, but returns false if the surface hasn't yet
8480 * been drawn.
8481 */
8482 public boolean isDisplayedLw() {
8483 final AppWindowToken atoken = mAppToken;
8484 return mSurface != null && mPolicyVisibility && !mDestroying
8485 && !mDrawPending && !mCommitDrawPending
8486 && ((!mAttachedHidden &&
8487 (atoken == null || !atoken.hiddenRequested))
8488 || mAnimating);
8489 }
8490
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008491 /**
8492 * Returns true if the window has a surface that it has drawn a
8493 * complete UI in to.
8494 */
8495 public boolean isDrawnLw() {
8496 final AppWindowToken atoken = mAppToken;
8497 return mSurface != null && !mDestroying
8498 && !mDrawPending && !mCommitDrawPending;
8499 }
8500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 public boolean fillsScreenLw(int screenWidth, int screenHeight,
8502 boolean shownFrame, boolean onlyOpaque) {
8503 if (mSurface == null) {
8504 return false;
8505 }
8506 if (mAppToken != null && !mAppToken.appFullscreen) {
8507 return false;
8508 }
8509 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
8510 return false;
8511 }
8512 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008513
8514 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
8515 return frame.left <= mCompatibleScreenFrame.left &&
8516 frame.top <= mCompatibleScreenFrame.top &&
8517 frame.right >= mCompatibleScreenFrame.right &&
8518 frame.bottom >= mCompatibleScreenFrame.bottom;
8519 } else {
8520 return frame.left <= 0 && frame.top <= 0
8521 && frame.right >= screenWidth
8522 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 }
Romain Guy06882f82009-06-10 13:36:04 -07008525
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008526 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008527 * Return true if the window is opaque and fully drawn. This indicates
8528 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008529 */
8530 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008531 return (mAttrs.format == PixelFormat.OPAQUE
8532 || mAttrs.type == TYPE_WALLPAPER)
8533 && mSurface != null && mAnimation == null
8534 && (mAppToken == null || mAppToken.animation == null)
8535 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008536 }
8537
8538 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8539 return
8540 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008541 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8542 // only if it's visible
8543 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008544 // and only if the application fills the compatible screen
8545 mFrame.left <= mCompatibleScreenFrame.left &&
8546 mFrame.top <= mCompatibleScreenFrame.top &&
8547 mFrame.right >= mCompatibleScreenFrame.right &&
8548 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008549 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008550 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008551 }
8552
8553 boolean isFullscreen(int screenWidth, int screenHeight) {
8554 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008555 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008556 }
8557
8558 void removeLocked() {
8559 if (mAttachedWindow != null) {
8560 mAttachedWindow.mChildWindows.remove(this);
8561 }
8562 destroySurfaceLocked();
8563 mSession.windowRemovedLocked();
8564 try {
8565 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8566 } catch (RuntimeException e) {
8567 // Ignore if it has already been removed (usually because
8568 // we are doing this as part of processing a death note.)
8569 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008570
8571 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8572 if (mInputChannel != null) {
8573 mInputManager.unregisterInputChannel(mInputChannel);
8574
8575 mInputChannel.dispose();
8576 mInputChannel = null;
8577 }
8578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 }
8580
8581 private class DeathRecipient implements IBinder.DeathRecipient {
8582 public void binderDied() {
8583 try {
8584 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008585 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008586 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 if (win != null) {
8588 removeWindowLocked(mSession, win);
8589 }
8590 }
8591 } catch (IllegalArgumentException ex) {
8592 // This will happen if the window has already been
8593 // removed.
8594 }
8595 }
8596 }
8597
8598 /** Returns true if this window desires key events. */
8599 public final boolean canReceiveKeys() {
8600 return isVisibleOrAdding()
8601 && (mViewVisibility == View.VISIBLE)
8602 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8603 }
8604
8605 public boolean hasDrawnLw() {
8606 return mHasDrawn;
8607 }
8608
8609 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008610 return showLw(doAnimation, true);
8611 }
8612
8613 boolean showLw(boolean doAnimation, boolean requestAnim) {
8614 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8615 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008616 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008617 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008618 if (doAnimation) {
8619 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8620 + mPolicyVisibility + " mAnimation=" + mAnimation);
8621 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8622 doAnimation = false;
8623 } else if (mPolicyVisibility && mAnimation == null) {
8624 // Check for the case where we are currently visible and
8625 // not animating; we do not want to do animation at such a
8626 // point to become visible when we already are.
8627 doAnimation = false;
8628 }
8629 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008630 mPolicyVisibility = true;
8631 mPolicyVisibilityAfterAnim = true;
8632 if (doAnimation) {
8633 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8634 }
8635 if (requestAnim) {
8636 requestAnimationLocked(0);
8637 }
8638 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008639 }
8640
8641 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008642 return hideLw(doAnimation, true);
8643 }
8644
8645 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008646 if (doAnimation) {
8647 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8648 doAnimation = false;
8649 }
8650 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8652 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008653 if (!current) {
8654 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008656 if (doAnimation) {
8657 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8658 if (mAnimation == null) {
8659 doAnimation = false;
8660 }
8661 }
8662 if (doAnimation) {
8663 mPolicyVisibilityAfterAnim = false;
8664 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008665 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008666 mPolicyVisibilityAfterAnim = false;
8667 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008668 // Window is no longer visible -- make sure if we were waiting
8669 // for it to be displayed before enabling the display, that
8670 // we allow the display to be enabled now.
8671 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008672 if (mCurrentFocus == this) {
8673 mFocusMayChange = true;
8674 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008675 }
8676 if (requestAnim) {
8677 requestAnimationLocked(0);
8678 }
8679 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 }
8681
8682 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008683 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8684 pw.print(" mClient="); pw.println(mClient.asBinder());
8685 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8686 if (mAttachedWindow != null || mLayoutAttached) {
8687 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8688 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8689 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008690 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8691 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8692 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008693 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8694 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008695 }
8696 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8697 pw.print(" mSubLayer="); pw.print(mSubLayer);
8698 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8699 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8700 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8701 pw.print("="); pw.print(mAnimLayer);
8702 pw.print(" mLastLayer="); pw.println(mLastLayer);
8703 if (mSurface != null) {
8704 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008705 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8706 pw.print(" layer="); pw.print(mSurfaceLayer);
8707 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8708 pw.print(" rect=("); pw.print(mSurfaceX);
8709 pw.print(","); pw.print(mSurfaceY);
8710 pw.print(") "); pw.print(mSurfaceW);
8711 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008712 }
8713 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8714 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8715 if (mAppToken != null) {
8716 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8717 }
8718 if (mTargetAppToken != null) {
8719 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8720 }
8721 pw.print(prefix); pw.print("mViewVisibility=0x");
8722 pw.print(Integer.toHexString(mViewVisibility));
8723 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008724 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8725 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008726 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8727 pw.print(prefix); pw.print("mPolicyVisibility=");
8728 pw.print(mPolicyVisibility);
8729 pw.print(" mPolicyVisibilityAfterAnim=");
8730 pw.print(mPolicyVisibilityAfterAnim);
8731 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8732 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008733 if (!mRelayoutCalled) {
8734 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8735 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008736 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008737 pw.print(" h="); pw.print(mRequestedHeight);
8738 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008739 if (mXOffset != 0 || mYOffset != 0) {
8740 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8741 pw.print(" y="); pw.println(mYOffset);
8742 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008743 pw.print(prefix); pw.print("mGivenContentInsets=");
8744 mGivenContentInsets.printShortString(pw);
8745 pw.print(" mGivenVisibleInsets=");
8746 mGivenVisibleInsets.printShortString(pw);
8747 pw.println();
8748 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8749 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8750 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8751 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008752 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008753 pw.print(prefix); pw.print("mShownFrame=");
8754 mShownFrame.printShortString(pw);
8755 pw.print(" last="); mLastShownFrame.printShortString(pw);
8756 pw.println();
8757 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8758 pw.print(" last="); mLastFrame.printShortString(pw);
8759 pw.println();
8760 pw.print(prefix); pw.print("mContainingFrame=");
8761 mContainingFrame.printShortString(pw);
8762 pw.print(" mDisplayFrame=");
8763 mDisplayFrame.printShortString(pw);
8764 pw.println();
8765 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8766 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8767 pw.println();
8768 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8769 pw.print(" last="); mLastContentInsets.printShortString(pw);
8770 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8771 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8772 pw.println();
8773 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8774 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8775 pw.print(" mAlpha="); pw.print(mAlpha);
8776 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8777 }
8778 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8779 || mAnimation != null) {
8780 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8781 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8782 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8783 pw.print(" mAnimation="); pw.println(mAnimation);
8784 }
8785 if (mHasTransformation || mHasLocalTransformation) {
8786 pw.print(prefix); pw.print("XForm: has=");
8787 pw.print(mHasTransformation);
8788 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8789 pw.print(" "); mTransformation.printShortString(pw);
8790 pw.println();
8791 }
8792 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8793 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8794 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8795 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8796 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8797 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8798 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8799 pw.print(" mDestroying="); pw.print(mDestroying);
8800 pw.print(" mRemoved="); pw.println(mRemoved);
8801 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008802 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008803 pw.print(prefix); pw.print("mOrientationChanging=");
8804 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008805 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8806 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008807 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008808 if (mHScale != 1 || mVScale != 1) {
8809 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8810 pw.print(" mVScale="); pw.println(mVScale);
8811 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008812 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008813 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8814 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8815 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008816 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8817 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8818 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008821
8822 String makeInputChannelName() {
8823 return Integer.toHexString(System.identityHashCode(this))
8824 + " " + mAttrs.getTitle();
8825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826
8827 @Override
8828 public String toString() {
8829 return "Window{"
8830 + Integer.toHexString(System.identityHashCode(this))
8831 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
8832 }
8833 }
Romain Guy06882f82009-06-10 13:36:04 -07008834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008835 // -------------------------------------------------------------
8836 // Window Token State
8837 // -------------------------------------------------------------
8838
8839 class WindowToken {
8840 // The actual token.
8841 final IBinder token;
8842
8843 // The type of window this token is for, as per WindowManager.LayoutParams.
8844 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008846 // Set if this token was explicitly added by a client, so should
8847 // not be removed when all windows are removed.
8848 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008849
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008850 // For printing.
8851 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008853 // If this is an AppWindowToken, this is non-null.
8854 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 // All of the windows associated with this token.
8857 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8858
8859 // Is key dispatching paused for this token?
8860 boolean paused = false;
8861
8862 // Should this token's windows be hidden?
8863 boolean hidden;
8864
8865 // Temporary for finding which tokens no longer have visible windows.
8866 boolean hasVisible;
8867
Dianne Hackborna8f60182009-09-01 19:01:50 -07008868 // Set to true when this token is in a pending transaction where it
8869 // will be shown.
8870 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008871
Dianne Hackborna8f60182009-09-01 19:01:50 -07008872 // Set to true when this token is in a pending transaction where it
8873 // will be hidden.
8874 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008875
Dianne Hackborna8f60182009-09-01 19:01:50 -07008876 // Set to true when this token is in a pending transaction where its
8877 // windows will be put to the bottom of the list.
8878 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008879
Dianne Hackborna8f60182009-09-01 19:01:50 -07008880 // Set to true when this token is in a pending transaction where its
8881 // windows will be put to the top of the list.
8882 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008884 WindowToken(IBinder _token, int type, boolean _explicit) {
8885 token = _token;
8886 windowType = type;
8887 explicit = _explicit;
8888 }
8889
8890 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008891 pw.print(prefix); pw.print("token="); pw.println(token);
8892 pw.print(prefix); pw.print("windows="); pw.println(windows);
8893 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8894 pw.print(" hidden="); pw.print(hidden);
8895 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008896 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8897 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8898 pw.print(" waitingToHide="); pw.print(waitingToHide);
8899 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8900 pw.print(" sendingToTop="); pw.println(sendingToTop);
8901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008902 }
8903
8904 @Override
8905 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008906 if (stringName == null) {
8907 StringBuilder sb = new StringBuilder();
8908 sb.append("WindowToken{");
8909 sb.append(Integer.toHexString(System.identityHashCode(this)));
8910 sb.append(" token="); sb.append(token); sb.append('}');
8911 stringName = sb.toString();
8912 }
8913 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008914 }
8915 };
8916
8917 class AppWindowToken extends WindowToken {
8918 // Non-null only for application tokens.
8919 final IApplicationToken appToken;
8920
8921 // All of the windows and child windows that are included in this
8922 // application token. Note this list is NOT sorted!
8923 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8924
8925 int groupId = -1;
8926 boolean appFullscreen;
8927 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Romain Guy06882f82009-06-10 13:36:04 -07008928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008929 // These are used for determining when all windows associated with
8930 // an activity have been drawn, so they can be made visible together
8931 // at the same time.
8932 int lastTransactionSequence = mTransactionSequence-1;
8933 int numInterestingWindows;
8934 int numDrawnWindows;
8935 boolean inPendingTransaction;
8936 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008938 // Is this token going to be hidden in a little while? If so, it
8939 // won't be taken into account for setting the screen orientation.
8940 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008942 // Is this window's surface needed? This is almost like hidden, except
8943 // it will sometimes be true a little earlier: when the token has
8944 // been shown, but is still waiting for its app transition to execute
8945 // before making its windows shown.
8946 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008948 // Have we told the window clients to hide themselves?
8949 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008951 // Last visibility state we reported to the app token.
8952 boolean reportedVisible;
8953
8954 // Set to true when the token has been removed from the window mgr.
8955 boolean removed;
8956
8957 // Have we been asked to have this token keep the screen frozen?
8958 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008960 boolean animating;
8961 Animation animation;
8962 boolean hasTransformation;
8963 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008965 // Offset to the window of all layers in the token, for use by
8966 // AppWindowToken animations.
8967 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008969 // Information about an application starting window if displayed.
8970 StartingData startingData;
8971 WindowState startingWindow;
8972 View startingView;
8973 boolean startingDisplayed;
8974 boolean startingMoved;
8975 boolean firstWindowDrawn;
8976
8977 AppWindowToken(IApplicationToken _token) {
8978 super(_token.asBinder(),
8979 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8980 appWindowToken = this;
8981 appToken = _token;
8982 }
Romain Guy06882f82009-06-10 13:36:04 -07008983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008984 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008985 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008986 TAG, "Setting animation in " + this + ": " + anim);
8987 animation = anim;
8988 animating = false;
8989 anim.restrictDuration(MAX_ANIMATION_DURATION);
8990 anim.scaleCurrentDuration(mTransitionAnimationScale);
8991 int zorder = anim.getZAdjustment();
8992 int adj = 0;
8993 if (zorder == Animation.ZORDER_TOP) {
8994 adj = TYPE_LAYER_OFFSET;
8995 } else if (zorder == Animation.ZORDER_BOTTOM) {
8996 adj = -TYPE_LAYER_OFFSET;
8997 }
Romain Guy06882f82009-06-10 13:36:04 -07008998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008999 if (animLayerAdjustment != adj) {
9000 animLayerAdjustment = adj;
9001 updateLayers();
9002 }
9003 }
Romain Guy06882f82009-06-10 13:36:04 -07009004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 public void setDummyAnimation() {
9006 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009007 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 TAG, "Setting dummy animation in " + this);
9009 animation = sDummyAnimation;
9010 }
9011 }
9012
9013 public void clearAnimation() {
9014 if (animation != null) {
9015 animation = null;
9016 animating = true;
9017 }
9018 }
Romain Guy06882f82009-06-10 13:36:04 -07009019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 void updateLayers() {
9021 final int N = allAppWindows.size();
9022 final int adj = animLayerAdjustment;
9023 for (int i=0; i<N; i++) {
9024 WindowState w = allAppWindows.get(i);
9025 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009026 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009027 + w.mAnimLayer);
9028 if (w == mInputMethodTarget) {
9029 setInputMethodAnimLayerAdjustment(adj);
9030 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009031 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07009032 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009033 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009034 }
9035 }
Romain Guy06882f82009-06-10 13:36:04 -07009036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 void sendAppVisibilityToClients() {
9038 final int N = allAppWindows.size();
9039 for (int i=0; i<N; i++) {
9040 WindowState win = allAppWindows.get(i);
9041 if (win == startingWindow && clientHidden) {
9042 // Don't hide the starting window.
9043 continue;
9044 }
9045 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009046 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009047 "Setting visibility of " + win + ": " + (!clientHidden));
9048 win.mClient.dispatchAppVisibility(!clientHidden);
9049 } catch (RemoteException e) {
9050 }
9051 }
9052 }
Romain Guy06882f82009-06-10 13:36:04 -07009053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 void showAllWindowsLocked() {
9055 final int NW = allAppWindows.size();
9056 for (int i=0; i<NW; i++) {
9057 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009058 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059 "performing show on: " + w);
9060 w.performShowLocked();
9061 }
9062 }
Romain Guy06882f82009-06-10 13:36:04 -07009063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009064 // This must be called while inside a transaction.
9065 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009066 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07009068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 if (animation == sDummyAnimation) {
9070 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009071 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009072 // when it is really time to animate, this will be set to
9073 // a real animation and the next call will execute normally.
9074 return false;
9075 }
Romain Guy06882f82009-06-10 13:36:04 -07009076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009077 if ((allDrawn || animating || startingDisplayed) && animation != null) {
9078 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009079 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 TAG, "Starting animation in " + this +
9081 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
9082 + " scale=" + mTransitionAnimationScale
9083 + " allDrawn=" + allDrawn + " animating=" + animating);
9084 animation.initialize(dw, dh, dw, dh);
9085 animation.setStartTime(currentTime);
9086 animating = true;
9087 }
9088 transformation.clear();
9089 final boolean more = animation.getTransformation(
9090 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009091 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009092 TAG, "Stepped animation in " + this +
9093 ": more=" + more + ", xform=" + transformation);
9094 if (more) {
9095 // we're done!
9096 hasTransformation = true;
9097 return true;
9098 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009099 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009100 TAG, "Finished animation in " + this +
9101 " @ " + currentTime);
9102 animation = null;
9103 }
9104 } else if (animation != null) {
9105 // If the display is frozen, and there is a pending animation,
9106 // clear it and make sure we run the cleanup code.
9107 animating = true;
9108 animation = null;
9109 }
9110
9111 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07009112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009113 if (!animating) {
9114 return false;
9115 }
9116
9117 clearAnimation();
9118 animating = false;
9119 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
9120 moveInputMethodWindowsIfNeededLocked(true);
9121 }
Romain Guy06882f82009-06-10 13:36:04 -07009122
Joe Onorato8a9b2202010-02-26 18:56:32 -08009123 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009124 TAG, "Animation done in " + this
9125 + ": reportedVisible=" + reportedVisible);
9126
9127 transformation.clear();
9128 if (animLayerAdjustment != 0) {
9129 animLayerAdjustment = 0;
9130 updateLayers();
9131 }
Romain Guy06882f82009-06-10 13:36:04 -07009132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009133 final int N = windows.size();
9134 for (int i=0; i<N; i++) {
9135 ((WindowState)windows.get(i)).finishExit();
9136 }
9137 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07009138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139 return false;
9140 }
9141
9142 void updateReportedVisibilityLocked() {
9143 if (appToken == null) {
9144 return;
9145 }
Romain Guy06882f82009-06-10 13:36:04 -07009146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009147 int numInteresting = 0;
9148 int numVisible = 0;
9149 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07009150
Joe Onorato8a9b2202010-02-26 18:56:32 -08009151 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 final int N = allAppWindows.size();
9153 for (int i=0; i<N; i++) {
9154 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08009155 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07009156 || win.mViewVisibility != View.VISIBLE
9157 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009158 continue;
9159 }
9160 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009161 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009162 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009163 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009164 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009165 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009166 + " pv=" + win.mPolicyVisibility
9167 + " dp=" + win.mDrawPending
9168 + " cdp=" + win.mCommitDrawPending
9169 + " ah=" + win.mAttachedHidden
9170 + " th="
9171 + (win.mAppToken != null
9172 ? win.mAppToken.hiddenRequested : false)
9173 + " a=" + win.mAnimating);
9174 }
9175 }
9176 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009177 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009178 if (!win.isAnimating()) {
9179 numVisible++;
9180 }
9181 nowGone = false;
9182 } else if (win.isAnimating()) {
9183 nowGone = false;
9184 }
9185 }
Romain Guy06882f82009-06-10 13:36:04 -07009186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009188 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009189 + numInteresting + " visible=" + numVisible);
9190 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009191 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009192 TAG, "Visibility changed in " + this
9193 + ": vis=" + nowVisible);
9194 reportedVisible = nowVisible;
9195 Message m = mH.obtainMessage(
9196 H.REPORT_APPLICATION_TOKEN_WINDOWS,
9197 nowVisible ? 1 : 0,
9198 nowGone ? 1 : 0,
9199 this);
9200 mH.sendMessage(m);
9201 }
9202 }
Romain Guy06882f82009-06-10 13:36:04 -07009203
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009204 WindowState findMainWindow() {
9205 int j = windows.size();
9206 while (j > 0) {
9207 j--;
9208 WindowState win = windows.get(j);
9209 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
9210 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
9211 return win;
9212 }
9213 }
9214 return null;
9215 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217 void dump(PrintWriter pw, String prefix) {
9218 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009219 if (appToken != null) {
9220 pw.print(prefix); pw.println("app=true");
9221 }
9222 if (allAppWindows.size() > 0) {
9223 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
9224 }
9225 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009226 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009227 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
9228 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
9229 pw.print(" clientHidden="); pw.print(clientHidden);
9230 pw.print(" willBeHidden="); pw.print(willBeHidden);
9231 pw.print(" reportedVisible="); pw.println(reportedVisible);
9232 if (paused || freezingScreen) {
9233 pw.print(prefix); pw.print("paused="); pw.print(paused);
9234 pw.print(" freezingScreen="); pw.println(freezingScreen);
9235 }
9236 if (numInterestingWindows != 0 || numDrawnWindows != 0
9237 || inPendingTransaction || allDrawn) {
9238 pw.print(prefix); pw.print("numInterestingWindows=");
9239 pw.print(numInterestingWindows);
9240 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
9241 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
9242 pw.print(" allDrawn="); pw.println(allDrawn);
9243 }
9244 if (animating || animation != null) {
9245 pw.print(prefix); pw.print("animating="); pw.print(animating);
9246 pw.print(" animation="); pw.println(animation);
9247 }
9248 if (animLayerAdjustment != 0) {
9249 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
9250 }
9251 if (hasTransformation) {
9252 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
9253 pw.print(" transformation="); transformation.printShortString(pw);
9254 pw.println();
9255 }
9256 if (startingData != null || removed || firstWindowDrawn) {
9257 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
9258 pw.print(" removed="); pw.print(removed);
9259 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
9260 }
9261 if (startingWindow != null || startingView != null
9262 || startingDisplayed || startingMoved) {
9263 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
9264 pw.print(" startingView="); pw.print(startingView);
9265 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
9266 pw.print(" startingMoved"); pw.println(startingMoved);
9267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268 }
9269
9270 @Override
9271 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009272 if (stringName == null) {
9273 StringBuilder sb = new StringBuilder();
9274 sb.append("AppWindowToken{");
9275 sb.append(Integer.toHexString(System.identityHashCode(this)));
9276 sb.append(" token="); sb.append(token); sb.append('}');
9277 stringName = sb.toString();
9278 }
9279 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 }
9281 }
Romain Guy06882f82009-06-10 13:36:04 -07009282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283 // -------------------------------------------------------------
9284 // DummyAnimation
9285 // -------------------------------------------------------------
9286
9287 // This is an animation that does nothing: it just immediately finishes
9288 // itself every time it is called. It is used as a stub animation in cases
9289 // where we want to synchronize multiple things that may be animating.
9290 static final class DummyAnimation extends Animation {
9291 public boolean getTransformation(long currentTime, Transformation outTransformation) {
9292 return false;
9293 }
9294 }
9295 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07009296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 // -------------------------------------------------------------
9298 // Async Handler
9299 // -------------------------------------------------------------
9300
9301 static final class StartingData {
9302 final String pkg;
9303 final int theme;
9304 final CharSequence nonLocalizedLabel;
9305 final int labelRes;
9306 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07009307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009308 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
9309 int _labelRes, int _icon) {
9310 pkg = _pkg;
9311 theme = _theme;
9312 nonLocalizedLabel = _nonLocalizedLabel;
9313 labelRes = _labelRes;
9314 icon = _icon;
9315 }
9316 }
9317
9318 private final class H extends Handler {
9319 public static final int REPORT_FOCUS_CHANGE = 2;
9320 public static final int REPORT_LOSING_FOCUS = 3;
9321 public static final int ANIMATE = 4;
9322 public static final int ADD_STARTING = 5;
9323 public static final int REMOVE_STARTING = 6;
9324 public static final int FINISHED_STARTING = 7;
9325 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009326 public static final int WINDOW_FREEZE_TIMEOUT = 11;
9327 public static final int HOLD_SCREEN_CHANGED = 12;
9328 public static final int APP_TRANSITION_TIMEOUT = 13;
9329 public static final int PERSIST_ANIMATION_SCALE = 14;
9330 public static final int FORCE_GC = 15;
9331 public static final int ENABLE_SCREEN = 16;
9332 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009333 public static final int SEND_NEW_CONFIGURATION = 18;
Romain Guy06882f82009-06-10 13:36:04 -07009334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009335 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07009336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009337 public H() {
9338 }
Romain Guy06882f82009-06-10 13:36:04 -07009339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 @Override
9341 public void handleMessage(Message msg) {
9342 switch (msg.what) {
9343 case REPORT_FOCUS_CHANGE: {
9344 WindowState lastFocus;
9345 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07009346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 synchronized(mWindowMap) {
9348 lastFocus = mLastFocus;
9349 newFocus = mCurrentFocus;
9350 if (lastFocus == newFocus) {
9351 // Focus is not changing, so nothing to do.
9352 return;
9353 }
9354 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009355 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009356 // + " to " + newFocus);
9357 if (newFocus != null && lastFocus != null
9358 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009359 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009360 mLosingFocus.add(lastFocus);
9361 lastFocus = null;
9362 }
9363 }
9364
9365 if (lastFocus != newFocus) {
9366 //System.out.println("Changing focus from " + lastFocus
9367 // + " to " + newFocus);
9368 if (newFocus != null) {
9369 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009370 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
9372 } catch (RemoteException e) {
9373 // Ignore if process has died.
9374 }
9375 }
9376
9377 if (lastFocus != null) {
9378 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009379 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
9381 } catch (RemoteException e) {
9382 // Ignore if process has died.
9383 }
9384 }
9385 }
9386 } break;
9387
9388 case REPORT_LOSING_FOCUS: {
9389 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07009390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009391 synchronized(mWindowMap) {
9392 losers = mLosingFocus;
9393 mLosingFocus = new ArrayList<WindowState>();
9394 }
9395
9396 final int N = losers.size();
9397 for (int i=0; i<N; i++) {
9398 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009399 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
9401 } catch (RemoteException e) {
9402 // Ignore if process has died.
9403 }
9404 }
9405 } break;
9406
9407 case ANIMATE: {
9408 synchronized(mWindowMap) {
9409 mAnimationPending = false;
9410 performLayoutAndPlaceSurfacesLocked();
9411 }
9412 } break;
9413
9414 case ADD_STARTING: {
9415 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9416 final StartingData sd = wtoken.startingData;
9417
9418 if (sd == null) {
9419 // Animation has been canceled... do nothing.
9420 return;
9421 }
Romain Guy06882f82009-06-10 13:36:04 -07009422
Joe Onorato8a9b2202010-02-26 18:56:32 -08009423 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07009425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009426 View view = null;
9427 try {
9428 view = mPolicy.addStartingWindow(
9429 wtoken.token, sd.pkg,
9430 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
9431 sd.icon);
9432 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009433 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 }
9435
9436 if (view != null) {
9437 boolean abort = false;
9438
9439 synchronized(mWindowMap) {
9440 if (wtoken.removed || wtoken.startingData == null) {
9441 // If the window was successfully added, then
9442 // we need to remove it.
9443 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009444 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009445 "Aborted starting " + wtoken
9446 + ": removed=" + wtoken.removed
9447 + " startingData=" + wtoken.startingData);
9448 wtoken.startingWindow = null;
9449 wtoken.startingData = null;
9450 abort = true;
9451 }
9452 } else {
9453 wtoken.startingView = view;
9454 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009455 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 "Added starting " + wtoken
9457 + ": startingWindow="
9458 + wtoken.startingWindow + " startingView="
9459 + wtoken.startingView);
9460 }
9461
9462 if (abort) {
9463 try {
9464 mPolicy.removeStartingWindow(wtoken.token, view);
9465 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009466 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009467 }
9468 }
9469 }
9470 } break;
9471
9472 case REMOVE_STARTING: {
9473 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9474 IBinder token = null;
9475 View view = null;
9476 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009477 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009478 + wtoken + ": startingWindow="
9479 + wtoken.startingWindow + " startingView="
9480 + wtoken.startingView);
9481 if (wtoken.startingWindow != null) {
9482 view = wtoken.startingView;
9483 token = wtoken.token;
9484 wtoken.startingData = null;
9485 wtoken.startingView = null;
9486 wtoken.startingWindow = null;
9487 }
9488 }
9489 if (view != null) {
9490 try {
9491 mPolicy.removeStartingWindow(token, view);
9492 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009493 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 }
9495 }
9496 } break;
9497
9498 case FINISHED_STARTING: {
9499 IBinder token = null;
9500 View view = null;
9501 while (true) {
9502 synchronized (mWindowMap) {
9503 final int N = mFinishedStarting.size();
9504 if (N <= 0) {
9505 break;
9506 }
9507 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9508
Joe Onorato8a9b2202010-02-26 18:56:32 -08009509 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 "Finished starting " + wtoken
9511 + ": startingWindow=" + wtoken.startingWindow
9512 + " startingView=" + wtoken.startingView);
9513
9514 if (wtoken.startingWindow == null) {
9515 continue;
9516 }
9517
9518 view = wtoken.startingView;
9519 token = wtoken.token;
9520 wtoken.startingData = null;
9521 wtoken.startingView = null;
9522 wtoken.startingWindow = null;
9523 }
9524
9525 try {
9526 mPolicy.removeStartingWindow(token, view);
9527 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009528 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009529 }
9530 }
9531 } break;
9532
9533 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9534 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9535
9536 boolean nowVisible = msg.arg1 != 0;
9537 boolean nowGone = msg.arg2 != 0;
9538
9539 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009540 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 TAG, "Reporting visible in " + wtoken
9542 + " visible=" + nowVisible
9543 + " gone=" + nowGone);
9544 if (nowVisible) {
9545 wtoken.appToken.windowsVisible();
9546 } else {
9547 wtoken.appToken.windowsGone();
9548 }
9549 } catch (RemoteException ex) {
9550 }
9551 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 case WINDOW_FREEZE_TIMEOUT: {
9554 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009555 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009556 int i = mWindows.size();
9557 while (i > 0) {
9558 i--;
9559 WindowState w = (WindowState)mWindows.get(i);
9560 if (w.mOrientationChanging) {
9561 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009562 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 }
9564 }
9565 performLayoutAndPlaceSurfacesLocked();
9566 }
9567 break;
9568 }
Romain Guy06882f82009-06-10 13:36:04 -07009569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009570 case HOLD_SCREEN_CHANGED: {
9571 Session oldHold;
9572 Session newHold;
9573 synchronized (mWindowMap) {
9574 oldHold = mLastReportedHold;
9575 newHold = (Session)msg.obj;
9576 mLastReportedHold = newHold;
9577 }
Romain Guy06882f82009-06-10 13:36:04 -07009578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009579 if (oldHold != newHold) {
9580 try {
9581 if (oldHold != null) {
9582 mBatteryStats.noteStopWakelock(oldHold.mUid,
9583 "window",
9584 BatteryStats.WAKE_TYPE_WINDOW);
9585 }
9586 if (newHold != null) {
9587 mBatteryStats.noteStartWakelock(newHold.mUid,
9588 "window",
9589 BatteryStats.WAKE_TYPE_WINDOW);
9590 }
9591 } catch (RemoteException e) {
9592 }
9593 }
9594 break;
9595 }
Romain Guy06882f82009-06-10 13:36:04 -07009596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009597 case APP_TRANSITION_TIMEOUT: {
9598 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009599 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009600 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009601 "*** APP TRANSITION TIMEOUT");
9602 mAppTransitionReady = true;
9603 mAppTransitionTimeout = true;
9604 performLayoutAndPlaceSurfacesLocked();
9605 }
9606 }
9607 break;
9608 }
Romain Guy06882f82009-06-10 13:36:04 -07009609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009610 case PERSIST_ANIMATION_SCALE: {
9611 Settings.System.putFloat(mContext.getContentResolver(),
9612 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9613 Settings.System.putFloat(mContext.getContentResolver(),
9614 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9615 break;
9616 }
Romain Guy06882f82009-06-10 13:36:04 -07009617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 case FORCE_GC: {
9619 synchronized(mWindowMap) {
9620 if (mAnimationPending) {
9621 // If we are animating, don't do the gc now but
9622 // delay a bit so we don't interrupt the animation.
9623 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9624 2000);
9625 return;
9626 }
9627 // If we are currently rotating the display, it will
9628 // schedule a new message when done.
9629 if (mDisplayFrozen) {
9630 return;
9631 }
9632 mFreezeGcPending = 0;
9633 }
9634 Runtime.getRuntime().gc();
9635 break;
9636 }
Romain Guy06882f82009-06-10 13:36:04 -07009637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009638 case ENABLE_SCREEN: {
9639 performEnableScreen();
9640 break;
9641 }
Romain Guy06882f82009-06-10 13:36:04 -07009642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 case APP_FREEZE_TIMEOUT: {
9644 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009645 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009646 int i = mAppTokens.size();
9647 while (i > 0) {
9648 i--;
9649 AppWindowToken tok = mAppTokens.get(i);
9650 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009651 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 unsetAppFreezingScreenLocked(tok, true, true);
9653 }
9654 }
9655 }
9656 break;
9657 }
Romain Guy06882f82009-06-10 13:36:04 -07009658
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009659 case SEND_NEW_CONFIGURATION: {
9660 removeMessages(SEND_NEW_CONFIGURATION);
9661 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009662 break;
9663 }
Romain Guy06882f82009-06-10 13:36:04 -07009664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009665 }
9666 }
9667 }
9668
9669 // -------------------------------------------------------------
9670 // IWindowManager API
9671 // -------------------------------------------------------------
9672
9673 public IWindowSession openSession(IInputMethodClient client,
9674 IInputContext inputContext) {
9675 if (client == null) throw new IllegalArgumentException("null client");
9676 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009677 Session session = new Session(client, inputContext);
9678 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009679 }
9680
9681 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9682 synchronized (mWindowMap) {
9683 // The focus for the client is the window immediately below
9684 // where we would place the input method window.
9685 int idx = findDesiredInputMethodWindowIndexLocked(false);
9686 WindowState imFocus;
9687 if (idx > 0) {
9688 imFocus = (WindowState)mWindows.get(idx-1);
9689 if (imFocus != null) {
9690 if (imFocus.mSession.mClient != null &&
9691 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9692 return true;
9693 }
9694 }
9695 }
9696 }
9697 return false;
9698 }
Romain Guy06882f82009-06-10 13:36:04 -07009699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 // -------------------------------------------------------------
9701 // Internals
9702 // -------------------------------------------------------------
9703
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009704 final WindowState windowForClientLocked(Session session, IWindow client,
9705 boolean throwOnError) {
9706 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009707 }
Romain Guy06882f82009-06-10 13:36:04 -07009708
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009709 final WindowState windowForClientLocked(Session session, IBinder client,
9710 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009711 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009712 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 TAG, "Looking up client " + client + ": " + win);
9714 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009715 RuntimeException ex = new IllegalArgumentException(
9716 "Requested window " + client + " does not exist");
9717 if (throwOnError) {
9718 throw ex;
9719 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009720 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 return null;
9722 }
9723 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009724 RuntimeException ex = new IllegalArgumentException(
9725 "Requested window " + client + " is in session " +
9726 win.mSession + ", not " + session);
9727 if (throwOnError) {
9728 throw ex;
9729 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009730 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731 return null;
9732 }
9733
9734 return win;
9735 }
9736
Dianne Hackborna8f60182009-09-01 19:01:50 -07009737 final void rebuildAppWindowListLocked() {
9738 int NW = mWindows.size();
9739 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009740 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009741 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009742
Dianne Hackborna8f60182009-09-01 19:01:50 -07009743 // First remove all existing app windows.
9744 i=0;
9745 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009746 WindowState w = (WindowState)mWindows.get(i);
9747 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009748 WindowState win = (WindowState)mWindows.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009749 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009750 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009751 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009752 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009753 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009754 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9755 && lastWallpaper == i-1) {
9756 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009757 }
9758 i++;
9759 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009760
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009761 // The wallpaper window(s) typically live at the bottom of the stack,
9762 // so skip them before adding app tokens.
9763 lastWallpaper++;
9764 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009765
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009766 // First add all of the exiting app tokens... these are no longer
9767 // in the main app list, but still have windows shown. We put them
9768 // in the back because now that the animation is over we no longer
9769 // will care about them.
9770 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009771 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009772 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9773 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009774
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009775 // And add in the still active app tokens in Z order.
9776 NT = mAppTokens.size();
9777 for (int j=0; j<NT; j++) {
9778 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009780
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009781 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009782 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009783 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009784 + " windows but added " + i);
9785 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009786 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788 private final void assignLayersLocked() {
9789 int N = mWindows.size();
9790 int curBaseLayer = 0;
9791 int curLayer = 0;
9792 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 for (i=0; i<N; i++) {
9795 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009796 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9797 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 curLayer += WINDOW_LAYER_MULTIPLIER;
9799 w.mLayer = curLayer;
9800 } else {
9801 curBaseLayer = curLayer = w.mBaseLayer;
9802 w.mLayer = curLayer;
9803 }
9804 if (w.mTargetAppToken != null) {
9805 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9806 } else if (w.mAppToken != null) {
9807 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9808 } else {
9809 w.mAnimLayer = w.mLayer;
9810 }
9811 if (w.mIsImWindow) {
9812 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009813 } else if (w.mIsWallpaper) {
9814 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009816 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 + w.mAnimLayer);
9818 //System.out.println(
9819 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9820 }
9821 }
9822
9823 private boolean mInLayout = false;
9824 private final void performLayoutAndPlaceSurfacesLocked() {
9825 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009826 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009827 throw new RuntimeException("Recursive call!");
9828 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009829 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009830 return;
9831 }
9832
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009833 if (mWaitingForConfig) {
9834 // Our configuration has changed (most likely rotation), but we
9835 // don't yet have the complete configuration to report to
9836 // applications. Don't do any window layout until we have it.
9837 return;
9838 }
9839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 boolean recoveringMemory = false;
9841 if (mForceRemoves != null) {
9842 recoveringMemory = true;
9843 // Wait a little it for things to settle down, and off we go.
9844 for (int i=0; i<mForceRemoves.size(); i++) {
9845 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009846 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009847 removeWindowInnerLocked(ws.mSession, ws);
9848 }
9849 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009850 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 Object tmp = new Object();
9852 synchronized (tmp) {
9853 try {
9854 tmp.wait(250);
9855 } catch (InterruptedException e) {
9856 }
9857 }
9858 }
Romain Guy06882f82009-06-10 13:36:04 -07009859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 mInLayout = true;
9861 try {
9862 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 int i = mPendingRemove.size()-1;
9865 if (i >= 0) {
9866 while (i >= 0) {
9867 WindowState w = mPendingRemove.get(i);
9868 removeWindowInnerLocked(w.mSession, w);
9869 i--;
9870 }
9871 mPendingRemove.clear();
9872
9873 mInLayout = false;
9874 assignLayersLocked();
9875 mLayoutNeeded = true;
9876 performLayoutAndPlaceSurfacesLocked();
9877
9878 } else {
9879 mInLayout = false;
9880 if (mLayoutNeeded) {
9881 requestAnimationLocked(0);
9882 }
9883 }
9884 } catch (RuntimeException e) {
9885 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009886 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 }
9888 }
9889
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009890 private final int performLayoutLockedInner() {
9891 if (!mLayoutNeeded) {
9892 return 0;
9893 }
9894
9895 mLayoutNeeded = false;
9896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009897 final int dw = mDisplay.getWidth();
9898 final int dh = mDisplay.getHeight();
9899
9900 final int N = mWindows.size();
9901 int i;
9902
Joe Onorato8a9b2202010-02-26 18:56:32 -08009903 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009904 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9905
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009906 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009907
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009908 int seq = mLayoutSeq+1;
9909 if (seq < 0) seq = 0;
9910 mLayoutSeq = seq;
9911
9912 // First perform layout of any root windows (not attached
9913 // to another window).
9914 int topAttached = -1;
9915 for (i = N-1; i >= 0; i--) {
9916 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009917
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009918 // Don't do layout of a window if it is not visible, or
9919 // soon won't be visible, to avoid wasting time and funky
9920 // changes while a window is animating away.
9921 final AppWindowToken atoken = win.mAppToken;
9922 final boolean gone = win.mViewVisibility == View.GONE
9923 || !win.mRelayoutCalled
9924 || win.mRootToken.hidden
9925 || (atoken != null && atoken.hiddenRequested)
9926 || win.mAttachedHidden
9927 || win.mExiting || win.mDestroying;
9928
9929 if (!win.mLayoutAttached) {
9930 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
9931 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9932 + " mLayoutAttached=" + win.mLayoutAttached);
9933 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
9934 + win.mViewVisibility + " mRelayoutCalled="
9935 + win.mRelayoutCalled + " hidden="
9936 + win.mRootToken.hidden + " hiddenRequested="
9937 + (atoken != null && atoken.hiddenRequested)
9938 + " mAttachedHidden=" + win.mAttachedHidden);
9939 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009940
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009941 // If this view is GONE, then skip it -- keep the current
9942 // frame, and let the caller know so they can ignore it
9943 // if they want. (We do the normal layout for INVISIBLE
9944 // windows, since that means "perform layout as normal,
9945 // just don't display").
9946 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009947 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009948 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9949 win.mLayoutSeq = seq;
9950 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9951 + win.mFrame + " mContainingFrame="
9952 + win.mContainingFrame + " mDisplayFrame="
9953 + win.mDisplayFrame);
9954 } else {
9955 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009956 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009958 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009959
9960 // Now perform layout of attached windows, which usually
9961 // depend on the position of the window they are attached to.
9962 // XXX does not deal with windows that are attached to windows
9963 // that are themselves attached.
9964 for (i = topAttached; i >= 0; i--) {
9965 WindowState win = (WindowState) mWindows.get(i);
9966
9967 // If this view is GONE, then skip it -- keep the current
9968 // frame, and let the caller know so they can ignore it
9969 // if they want. (We do the normal layout for INVISIBLE
9970 // windows, since that means "perform layout as normal,
9971 // just don't display").
9972 if (win.mLayoutAttached) {
9973 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9974 + " mHaveFrame=" + win.mHaveFrame
9975 + " mViewVisibility=" + win.mViewVisibility
9976 + " mRelayoutCalled=" + win.mRelayoutCalled);
9977 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9978 || !win.mHaveFrame) {
9979 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9980 win.mLayoutSeq = seq;
9981 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9982 + win.mFrame + " mContainingFrame="
9983 + win.mContainingFrame + " mDisplayFrame="
9984 + win.mDisplayFrame);
9985 }
9986 }
9987 }
9988
9989 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 }
Romain Guy06882f82009-06-10 13:36:04 -07009991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 private final void performLayoutAndPlaceSurfacesLockedInner(
9993 boolean recoveringMemory) {
9994 final long currentTime = SystemClock.uptimeMillis();
9995 final int dw = mDisplay.getWidth();
9996 final int dh = mDisplay.getHeight();
9997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998 int i;
9999
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010000 if (mFocusMayChange) {
10001 mFocusMayChange = false;
10002 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
10003 }
10004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 if (mFxSession == null) {
10006 mFxSession = new SurfaceSession();
10007 }
Romain Guy06882f82009-06-10 13:36:04 -070010008
Joe Onorato8a9b2202010-02-26 18:56:32 -080010009 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010
10011 // Initialize state of exiting tokens.
10012 for (i=mExitingTokens.size()-1; i>=0; i--) {
10013 mExitingTokens.get(i).hasVisible = false;
10014 }
10015
10016 // Initialize state of exiting applications.
10017 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10018 mExitingAppTokens.get(i).hasVisible = false;
10019 }
10020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010021 boolean orientationChangeComplete = true;
10022 Session holdScreen = null;
10023 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010024 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 boolean focusDisplayed = false;
10026 boolean animating = false;
10027
10028 Surface.openTransaction();
10029 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010030 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010031 int repeats = 0;
10032 int changes = 0;
10033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010034 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010035 repeats++;
10036 if (repeats > 6) {
10037 Slog.w(TAG, "Animation repeat aborted after too many iterations");
10038 mLayoutNeeded = false;
10039 break;
10040 }
10041
10042 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
10043 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
10044 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
10045 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
10046 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
10047 assignLayersLocked();
10048 mLayoutNeeded = true;
10049 }
10050 }
10051 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
10052 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
10053 if (updateOrientationFromAppTokensLocked()) {
10054 mLayoutNeeded = true;
10055 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10056 }
10057 }
10058 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
10059 mLayoutNeeded = true;
10060 }
10061 }
10062
10063 // FIRST LOOP: Perform a layout, if needed.
10064 if (repeats < 4) {
10065 changes = performLayoutLockedInner();
10066 if (changes != 0) {
10067 continue;
10068 }
10069 } else {
10070 Slog.w(TAG, "Layout repeat skipped after too many iterations");
10071 changes = 0;
10072 }
10073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010074 final int transactionSequence = ++mTransactionSequence;
10075
10076 // Update animations of all applications, including those
10077 // associated with exiting/removed apps
10078 boolean tokensAnimating = false;
10079 final int NAT = mAppTokens.size();
10080 for (i=0; i<NAT; i++) {
10081 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10082 tokensAnimating = true;
10083 }
10084 }
10085 final int NEAT = mExitingAppTokens.size();
10086 for (i=0; i<NEAT; i++) {
10087 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10088 tokensAnimating = true;
10089 }
10090 }
10091
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010092 // SECOND LOOP: Execute animations and update visibility of windows.
10093
Joe Onorato8a9b2202010-02-26 18:56:32 -080010094 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010095 + transactionSequence + " tokensAnimating="
10096 + tokensAnimating);
10097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010099
10100 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010101 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010102 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103
10104 mPolicy.beginAnimationLw(dw, dh);
10105
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010106 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010108 for (i=N-1; i>=0; i--) {
10109 WindowState w = (WindowState)mWindows.get(i);
10110
10111 final WindowManager.LayoutParams attrs = w.mAttrs;
10112
10113 if (w.mSurface != null) {
10114 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010115 if (w.commitFinishDrawingLocked(currentTime)) {
10116 if ((w.mAttrs.flags
10117 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010118 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010119 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010120 wallpaperMayChange = true;
10121 }
10122 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010123
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010124 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 if (w.stepAnimationLocked(currentTime, dw, dh)) {
10126 animating = true;
10127 //w.dump(" ");
10128 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010129 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
10130 wallpaperMayChange = true;
10131 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010132
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010133 if (mPolicy.doesForceHide(w, attrs)) {
10134 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010135 if (DEBUG_VISIBILITY) Slog.v(TAG,
10136 "Animation done that could impact force hide: "
10137 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010138 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010139 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010140 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
10141 forceHiding = true;
10142 }
10143 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10144 boolean changed;
10145 if (forceHiding) {
10146 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010147 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10148 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010149 } else {
10150 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010151 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10152 "Now policy shown: " + w);
10153 if (changed) {
10154 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010155 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010156 // Assume we will need to animate. If
10157 // we don't (because the wallpaper will
10158 // stay with the lock screen), then we will
10159 // clean up later.
10160 Animation a = mPolicy.createForceHideEnterAnimation();
10161 if (a != null) {
10162 w.setAnimation(a);
10163 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010164 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010165 if (mCurrentFocus == null ||
10166 mCurrentFocus.mLayer < w.mLayer) {
10167 // We are showing on to of the current
10168 // focus, so re-evaluate focus to make
10169 // sure it is correct.
10170 mFocusMayChange = true;
10171 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010172 }
10173 }
10174 if (changed && (attrs.flags
10175 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
10176 wallpaperMayChange = true;
10177 }
10178 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 mPolicy.animatingWindowLw(w, attrs);
10181 }
10182
10183 final AppWindowToken atoken = w.mAppToken;
10184 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
10185 if (atoken.lastTransactionSequence != transactionSequence) {
10186 atoken.lastTransactionSequence = transactionSequence;
10187 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
10188 atoken.startingDisplayed = false;
10189 }
10190 if ((w.isOnScreen() || w.mAttrs.type
10191 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
10192 && !w.mExiting && !w.mDestroying) {
10193 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010194 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010195 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010197 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010198 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 + " pv=" + w.mPolicyVisibility
10200 + " dp=" + w.mDrawPending
10201 + " cdp=" + w.mCommitDrawPending
10202 + " ah=" + w.mAttachedHidden
10203 + " th=" + atoken.hiddenRequested
10204 + " a=" + w.mAnimating);
10205 }
10206 }
10207 if (w != atoken.startingWindow) {
10208 if (!atoken.freezingScreen || !w.mAppFreezing) {
10209 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010210 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010211 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010212 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 "tokenMayBeDrawn: " + atoken
10214 + " freezingScreen=" + atoken.freezingScreen
10215 + " mAppFreezing=" + w.mAppFreezing);
10216 tokenMayBeDrawn = true;
10217 }
10218 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010219 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010220 atoken.startingDisplayed = true;
10221 }
10222 }
10223 } else if (w.mReadyToShow) {
10224 w.performShowLocked();
10225 }
10226 }
10227
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010228 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010229
10230 if (tokenMayBeDrawn) {
10231 // See if any windows have been drawn, so they (and others
10232 // associated with them) can now be shown.
10233 final int NT = mTokenList.size();
10234 for (i=0; i<NT; i++) {
10235 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
10236 if (wtoken == null) {
10237 continue;
10238 }
10239 if (wtoken.freezingScreen) {
10240 int numInteresting = wtoken.numInterestingWindows;
10241 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010242 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243 "allDrawn: " + wtoken
10244 + " interesting=" + numInteresting
10245 + " drawn=" + wtoken.numDrawnWindows);
10246 wtoken.showAllWindowsLocked();
10247 unsetAppFreezingScreenLocked(wtoken, false, true);
10248 orientationChangeComplete = true;
10249 }
10250 } else if (!wtoken.allDrawn) {
10251 int numInteresting = wtoken.numInterestingWindows;
10252 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010253 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 "allDrawn: " + wtoken
10255 + " interesting=" + numInteresting
10256 + " drawn=" + wtoken.numDrawnWindows);
10257 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010258 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010259
10260 // We can now show all of the drawn windows!
10261 if (!mOpeningApps.contains(wtoken)) {
10262 wtoken.showAllWindowsLocked();
10263 }
10264 }
10265 }
10266 }
10267 }
10268
10269 // If we are ready to perform an app transition, check through
10270 // all of the app tokens to be shown and see if they are ready
10271 // to go.
10272 if (mAppTransitionReady) {
10273 int NN = mOpeningApps.size();
10274 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010275 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276 "Checking " + NN + " opening apps (frozen="
10277 + mDisplayFrozen + " timeout="
10278 + mAppTransitionTimeout + ")...");
10279 if (!mDisplayFrozen && !mAppTransitionTimeout) {
10280 // If the display isn't frozen, wait to do anything until
10281 // all of the apps are ready. Otherwise just go because
10282 // we'll unfreeze the display when everyone is ready.
10283 for (i=0; i<NN && goodToGo; i++) {
10284 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010285 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010286 "Check opening app" + wtoken + ": allDrawn="
10287 + wtoken.allDrawn + " startingDisplayed="
10288 + wtoken.startingDisplayed);
10289 if (!wtoken.allDrawn && !wtoken.startingDisplayed
10290 && !wtoken.startingMoved) {
10291 goodToGo = false;
10292 }
10293 }
10294 }
10295 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010296 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 int transit = mNextAppTransition;
10298 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010299 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010301 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010303 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 mAppTransitionTimeout = false;
10305 mStartingIconInTransition = false;
10306 mSkipAppTransitionAnimation = false;
10307
10308 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
10309
Dianne Hackborna8f60182009-09-01 19:01:50 -070010310 // If there are applications waiting to come to the
10311 // top of the stack, now is the time to move their windows.
10312 // (Note that we don't do apps going to the bottom
10313 // here -- we want to keep their windows in the old
10314 // Z-order until the animation completes.)
10315 if (mToTopApps.size() > 0) {
10316 NN = mAppTokens.size();
10317 for (i=0; i<NN; i++) {
10318 AppWindowToken wtoken = mAppTokens.get(i);
10319 if (wtoken.sendingToTop) {
10320 wtoken.sendingToTop = false;
10321 moveAppWindowsLocked(wtoken, NN, false);
10322 }
10323 }
10324 mToTopApps.clear();
10325 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010326
Dianne Hackborn25994b42009-09-04 14:21:19 -070010327 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010328
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010329 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010330 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010331
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010332 // The top-most window will supply the layout params,
10333 // and we will determine it below.
10334 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010335 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010336 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010337
Joe Onorato8a9b2202010-02-26 18:56:32 -080010338 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010339 "New wallpaper target=" + mWallpaperTarget
10340 + ", lower target=" + mLowerWallpaperTarget
10341 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -070010342 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010343 // Do a first pass through the tokens for two
10344 // things:
10345 // (1) Determine if both the closing and opening
10346 // app token sets are wallpaper targets, in which
10347 // case special animations are needed
10348 // (since the wallpaper needs to stay static
10349 // behind them).
10350 // (2) Find the layout params of the top-most
10351 // application window in the tokens, which is
10352 // what will control the animation theme.
10353 final int NC = mClosingApps.size();
10354 NN = NC + mOpeningApps.size();
10355 for (i=0; i<NN; i++) {
10356 AppWindowToken wtoken;
10357 int mode;
10358 if (i < NC) {
10359 wtoken = mClosingApps.get(i);
10360 mode = 1;
10361 } else {
10362 wtoken = mOpeningApps.get(i-NC);
10363 mode = 2;
10364 }
10365 if (mLowerWallpaperTarget != null) {
10366 if (mLowerWallpaperTarget.mAppToken == wtoken
10367 || mUpperWallpaperTarget.mAppToken == wtoken) {
10368 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010369 }
10370 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010371 if (wtoken.appFullscreen) {
10372 WindowState ws = wtoken.findMainWindow();
10373 if (ws != null) {
10374 // If this is a compatibility mode
10375 // window, we will always use its anim.
10376 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
10377 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010378 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010379 bestAnimLayer = Integer.MAX_VALUE;
10380 } else if (ws.mLayer > bestAnimLayer) {
10381 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010382 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010383 bestAnimLayer = ws.mLayer;
10384 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010385 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010386 }
10387 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010388
Dianne Hackborn25994b42009-09-04 14:21:19 -070010389 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010390 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010391 "Wallpaper animation!");
10392 switch (transit) {
10393 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10394 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10395 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10396 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10397 break;
10398 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10399 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10400 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10401 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10402 break;
10403 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010404 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010405 "New transit: " + transit);
10406 } else if (oldWallpaper != null) {
10407 // We are transitioning from an activity with
10408 // a wallpaper to one without.
10409 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010410 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010411 "New transit away from wallpaper: " + transit);
10412 } else if (mWallpaperTarget != null) {
10413 // We are transitioning from an activity without
10414 // a wallpaper to now showing the wallpaper
10415 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010416 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010417 "New transit into wallpaper: " + transit);
10418 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010419
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010420 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
10421 mLastEnterAnimToken = animToken;
10422 mLastEnterAnimParams = animLp;
10423 } else if (mLastEnterAnimParams != null) {
10424 animLp = mLastEnterAnimParams;
10425 mLastEnterAnimToken = null;
10426 mLastEnterAnimParams = null;
10427 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010428
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010429 // If all closing windows are obscured, then there is
10430 // no need to do an animation. This is the case, for
10431 // example, when this transition is being done behind
10432 // the lock screen.
10433 if (!mPolicy.allowAppAnimationsLw()) {
10434 animLp = null;
10435 }
10436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010437 NN = mOpeningApps.size();
10438 for (i=0; i<NN; i++) {
10439 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010440 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010441 "Now opening app" + wtoken);
10442 wtoken.reportedVisible = false;
10443 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010444 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010445 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010446 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010447 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010448 wtoken.showAllWindowsLocked();
10449 }
10450 NN = mClosingApps.size();
10451 for (i=0; i<NN; i++) {
10452 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010453 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010454 "Now closing app" + wtoken);
10455 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010456 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010457 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010459 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010460 // Force the allDrawn flag, because we want to start
10461 // this guy's animations regardless of whether it's
10462 // gotten drawn.
10463 wtoken.allDrawn = true;
10464 }
10465
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010466 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010468 mOpeningApps.clear();
10469 mClosingApps.clear();
10470
10471 // This has changed the visibility of windows, so perform
10472 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010473 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010475 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10476 assignLayersLocked();
10477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010479 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010480 }
10481 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010482
Dianne Hackborn16064f92010-03-25 00:47:24 -070010483 int adjResult = 0;
10484
Dianne Hackborna8f60182009-09-01 19:01:50 -070010485 if (!animating && mAppTransitionRunning) {
10486 // We have finished the animation of an app transition. To do
10487 // this, we have delayed a lot of operations like showing and
10488 // hiding apps, moving apps in Z-order, etc. The app token list
10489 // reflects the correct Z-order, but the window list may now
10490 // be out of sync with it. So here we will just rebuild the
10491 // entire app window list. Fun!
10492 mAppTransitionRunning = false;
10493 // Clear information about apps that were moving.
10494 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010495
Dianne Hackborna8f60182009-09-01 19:01:50 -070010496 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010497 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010498 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010499 moveInputMethodWindowsIfNeededLocked(false);
10500 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010501 // Since the window list has been rebuilt, focus might
10502 // have to be recomputed since the actual order of windows
10503 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010504 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010505 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010506
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010507 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010508 // At this point, there was a window with a wallpaper that
10509 // was force hiding other windows behind it, but now it
10510 // is going away. This may be simple -- just animate
10511 // away the wallpaper and its window -- or it may be
10512 // hard -- the wallpaper now needs to be shown behind
10513 // something that was hidden.
10514 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010515 if (mLowerWallpaperTarget != null
10516 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010517 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010518 "wallpaperForceHiding changed with lower="
10519 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010520 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010521 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10522 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10523 if (mLowerWallpaperTarget.mAppToken.hidden) {
10524 // The lower target has become hidden before we
10525 // actually started the animation... let's completely
10526 // re-evaluate everything.
10527 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010528 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010529 }
10530 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010531 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010532 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010533 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010534 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010535 + " NEW: " + mWallpaperTarget
10536 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010537 if (mLowerWallpaperTarget == null) {
10538 // Whoops, we don't need a special wallpaper animation.
10539 // Clear them out.
10540 forceHiding = false;
10541 for (i=N-1; i>=0; i--) {
10542 WindowState w = (WindowState)mWindows.get(i);
10543 if (w.mSurface != null) {
10544 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010545 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010546 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010547 forceHiding = true;
10548 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10549 if (!w.mAnimating) {
10550 // We set the animation above so it
10551 // is not yet running.
10552 w.clearAnimation();
10553 }
10554 }
10555 }
10556 }
10557 }
10558 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010559
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010560 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010561 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010562 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010563 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010564 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010565
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010566 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010567 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010568 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010569 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010570 assignLayersLocked();
10571 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010572 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010573 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010574 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010575 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010576
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010577 if (mFocusMayChange) {
10578 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010579 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010580 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010581 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010582 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010583 }
10584
10585 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010586 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010587 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010588
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010589 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10590 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010591
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010592 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010593
10594 // THIRD LOOP: Update the surfaces of all windows.
10595
10596 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10597
10598 boolean obscured = false;
10599 boolean blurring = false;
10600 boolean dimming = false;
10601 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010602 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010603 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010605 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 for (i=N-1; i>=0; i--) {
10608 WindowState w = (WindowState)mWindows.get(i);
10609
10610 boolean displayed = false;
10611 final WindowManager.LayoutParams attrs = w.mAttrs;
10612 final int attrFlags = attrs.flags;
10613
10614 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010615 // XXX NOTE: The logic here could be improved. We have
10616 // the decision about whether to resize a window separated
10617 // from whether to hide the surface. This can cause us to
10618 // resize a surface even if we are going to hide it. You
10619 // can see this by (1) holding device in landscape mode on
10620 // home screen; (2) tapping browser icon (device will rotate
10621 // to landscape; (3) tap home. The wallpaper will be resized
10622 // in step 2 but then immediately hidden, causing us to
10623 // have to resize and then redraw it again in step 3. It
10624 // would be nice to figure out how to avoid this, but it is
10625 // difficult because we do need to resize surfaces in some
10626 // cases while they are hidden such as when first showing a
10627 // window.
10628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010630 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010631 TAG, "Placing surface #" + i + " " + w.mSurface
10632 + ": new=" + w.mShownFrame + ", old="
10633 + w.mLastShownFrame);
10634
10635 boolean resize;
10636 int width, height;
10637 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10638 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10639 w.mLastRequestedHeight != w.mRequestedHeight;
10640 // for a scaled surface, we just want to use
10641 // the requested size.
10642 width = w.mRequestedWidth;
10643 height = w.mRequestedHeight;
10644 w.mLastRequestedWidth = width;
10645 w.mLastRequestedHeight = height;
10646 w.mLastShownFrame.set(w.mShownFrame);
10647 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010648 if (SHOW_TRANSACTIONS) logSurface(w,
10649 "POS " + w.mShownFrame.left
10650 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010651 w.mSurfaceX = w.mShownFrame.left;
10652 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010653 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10654 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010655 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 if (!recoveringMemory) {
10657 reclaimSomeSurfaceMemoryLocked(w, "position");
10658 }
10659 }
10660 } else {
10661 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10662 width = w.mShownFrame.width();
10663 height = w.mShownFrame.height();
10664 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010665 }
10666
10667 if (resize) {
10668 if (width < 1) width = 1;
10669 if (height < 1) height = 1;
10670 if (w.mSurface != null) {
10671 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010672 if (SHOW_TRANSACTIONS) logSurface(w,
10673 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010674 + w.mShownFrame.top + " SIZE "
10675 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010676 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010677 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010678 w.mSurfaceW = width;
10679 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010680 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010681 w.mSurfaceX = w.mShownFrame.left;
10682 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 w.mSurface.setPosition(w.mShownFrame.left,
10684 w.mShownFrame.top);
10685 } catch (RuntimeException e) {
10686 // If something goes wrong with the surface (such
10687 // as running out of memory), don't take down the
10688 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010689 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010690 + "size=(" + width + "x" + height
10691 + "), pos=(" + w.mShownFrame.left
10692 + "," + w.mShownFrame.top + ")", e);
10693 if (!recoveringMemory) {
10694 reclaimSomeSurfaceMemoryLocked(w, "size");
10695 }
10696 }
10697 }
10698 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010699 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010700 w.mContentInsetsChanged =
10701 !w.mLastContentInsets.equals(w.mContentInsets);
10702 w.mVisibleInsetsChanged =
10703 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010704 boolean configChanged =
10705 w.mConfiguration != mCurConfiguration
10706 && (w.mConfiguration == null
10707 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010708 if (DEBUG_CONFIGURATION && configChanged) {
10709 Slog.v(TAG, "Win " + w + " config changed: "
10710 + mCurConfiguration);
10711 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010712 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010713 + ": configChanged=" + configChanged
10714 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010715 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010716 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010717 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010718 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010719 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010720 w.mLastFrame.set(w.mFrame);
10721 w.mLastContentInsets.set(w.mContentInsets);
10722 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010723 // If the screen is currently frozen, then keep
10724 // it frozen until this window draws at its new
10725 // orientation.
10726 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010727 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010728 "Resizing while display frozen: " + w);
10729 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010730 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010731 mWindowsFreezingScreen = true;
10732 // XXX should probably keep timeout from
10733 // when we first froze the display.
10734 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10735 mH.sendMessageDelayed(mH.obtainMessage(
10736 H.WINDOW_FREEZE_TIMEOUT), 2000);
10737 }
10738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 // If the orientation is changing, then we need to
10740 // hold off on unfreezing the display until this
10741 // window has been redrawn; to do that, we need
10742 // to go through the process of getting informed
10743 // by the application when it has finished drawing.
10744 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010745 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010746 "Orientation start waiting for draw in "
10747 + w + ", surface " + w.mSurface);
10748 w.mDrawPending = true;
10749 w.mCommitDrawPending = false;
10750 w.mReadyToShow = false;
10751 if (w.mAppToken != null) {
10752 w.mAppToken.allDrawn = false;
10753 }
10754 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010755 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010756 "Resizing window " + w + " to " + w.mFrame);
10757 mResizingWindows.add(w);
10758 } else if (w.mOrientationChanging) {
10759 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010760 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010761 "Orientation not waiting for draw in "
10762 + w + ", surface " + w.mSurface);
10763 w.mOrientationChanging = false;
10764 }
10765 }
10766 }
10767
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010768 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 if (!w.mLastHidden) {
10770 //dump();
10771 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010772 if (SHOW_TRANSACTIONS) logSurface(w,
10773 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010775 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010776 try {
10777 w.mSurface.hide();
10778 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010779 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 }
10781 }
10782 mKeyWaiter.releasePendingPointerLocked(w.mSession);
10783 }
10784 // If we are waiting for this window to handle an
10785 // orientation change, well, it is hidden, so
10786 // doesn't really matter. Note that this does
10787 // introduce a potential glitch if the window
10788 // becomes unhidden before it has drawn for the
10789 // new orientation.
10790 if (w.mOrientationChanging) {
10791 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010792 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010793 "Orientation change skips hidden " + w);
10794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010795 } else if (w.mLastLayer != w.mAnimLayer
10796 || w.mLastAlpha != w.mShownAlpha
10797 || w.mLastDsDx != w.mDsDx
10798 || w.mLastDtDx != w.mDtDx
10799 || w.mLastDsDy != w.mDsDy
10800 || w.mLastDtDy != w.mDtDy
10801 || w.mLastHScale != w.mHScale
10802 || w.mLastVScale != w.mVScale
10803 || w.mLastHidden) {
10804 displayed = true;
10805 w.mLastAlpha = w.mShownAlpha;
10806 w.mLastLayer = w.mAnimLayer;
10807 w.mLastDsDx = w.mDsDx;
10808 w.mLastDtDx = w.mDtDx;
10809 w.mLastDsDy = w.mDsDy;
10810 w.mLastDtDy = w.mDtDy;
10811 w.mLastHScale = w.mHScale;
10812 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010813 if (SHOW_TRANSACTIONS) logSurface(w,
10814 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010815 + " matrix=[" + (w.mDsDx*w.mHScale)
10816 + "," + (w.mDtDx*w.mVScale)
10817 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010818 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010819 if (w.mSurface != null) {
10820 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010821 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010823 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 w.mSurface.setLayer(w.mAnimLayer);
10825 w.mSurface.setMatrix(
10826 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10827 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10828 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010829 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830 if (!recoveringMemory) {
10831 reclaimSomeSurfaceMemoryLocked(w, "update");
10832 }
10833 }
10834 }
10835
10836 if (w.mLastHidden && !w.mDrawPending
10837 && !w.mCommitDrawPending
10838 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010839 if (SHOW_TRANSACTIONS) logSurface(w,
10840 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010841 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 + " during relayout");
10843 if (showSurfaceRobustlyLocked(w)) {
10844 w.mHasDrawn = true;
10845 w.mLastHidden = false;
10846 } else {
10847 w.mOrientationChanging = false;
10848 }
10849 }
10850 if (w.mSurface != null) {
10851 w.mToken.hasVisible = true;
10852 }
10853 } else {
10854 displayed = true;
10855 }
10856
10857 if (displayed) {
10858 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010859 if (attrs.width == LayoutParams.MATCH_PARENT
10860 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010861 covered = true;
10862 }
10863 }
10864 if (w.mOrientationChanging) {
10865 if (w.mDrawPending || w.mCommitDrawPending) {
10866 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010867 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010868 "Orientation continue waiting for draw in " + w);
10869 } else {
10870 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010871 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010872 "Orientation change complete in " + w);
10873 }
10874 }
10875 w.mToken.hasVisible = true;
10876 }
10877 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010878 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010879 "Orientation change skips hidden " + w);
10880 w.mOrientationChanging = false;
10881 }
10882
10883 final boolean canBeSeen = w.isDisplayedLw();
10884
10885 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10886 focusDisplayed = true;
10887 }
10888
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010889 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010891 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010892 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010893 if (w.mSurface != null) {
10894 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10895 holdScreen = w.mSession;
10896 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010897 if (!syswin && w.mAttrs.screenBrightness >= 0
10898 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 screenBrightness = w.mAttrs.screenBrightness;
10900 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010901 if (!syswin && w.mAttrs.buttonBrightness >= 0
10902 && buttonBrightness < 0) {
10903 buttonBrightness = w.mAttrs.buttonBrightness;
10904 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010905 if (canBeSeen
10906 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10907 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10908 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010909 syswin = true;
10910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010911 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010912
Dianne Hackborn25994b42009-09-04 14:21:19 -070010913 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10914 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 // This window completely covers everything behind it,
10916 // so we want to leave all of them as unblurred (for
10917 // performance reasons).
10918 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010919 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010920 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010921 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010922 obscured = true;
10923 if (mBackgroundFillerSurface == null) {
10924 try {
10925 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010926 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010927 0, dw, dh,
10928 PixelFormat.OPAQUE,
10929 Surface.FX_SURFACE_NORMAL);
10930 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010931 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010932 }
10933 }
10934 try {
10935 mBackgroundFillerSurface.setPosition(0, 0);
10936 mBackgroundFillerSurface.setSize(dw, dh);
10937 // Using the same layer as Dim because they will never be shown at the
10938 // same time.
10939 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10940 mBackgroundFillerSurface.show();
10941 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010942 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010943 }
10944 backgroundFillerShown = true;
10945 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010946 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010947 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010948 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949 + ": blurring=" + blurring
10950 + " obscured=" + obscured
10951 + " displayed=" + displayed);
10952 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10953 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010954 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010956 if (mDimAnimator == null) {
10957 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010958 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010959 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010960 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010962 }
10963 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10964 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010965 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010968 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010969 + mBlurSurface + ": CREATE");
10970 try {
Romain Guy06882f82009-06-10 13:36:04 -070010971 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010972 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 -1, 16, 16,
10974 PixelFormat.OPAQUE,
10975 Surface.FX_SURFACE_BLUR);
10976 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010977 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 }
10979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010980 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010981 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10982 + mBlurSurface + ": pos=(0,0) (" +
10983 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010984 mBlurSurface.setPosition(0, 0);
10985 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010986 mBlurSurface.setLayer(w.mAnimLayer-2);
10987 if (!mBlurShown) {
10988 try {
10989 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10990 + mBlurSurface + ": SHOW");
10991 mBlurSurface.show();
10992 } catch (RuntimeException e) {
10993 Slog.w(TAG, "Failure showing blur surface", e);
10994 }
10995 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010996 }
10997 }
10998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 }
11000 }
11001 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011002
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011003 if (obscuredChanged && mWallpaperTarget == w) {
11004 // This is the wallpaper target and its obscured state
11005 // changed... make sure the current wallaper's visibility
11006 // has been updated accordingly.
11007 updateWallpaperVisibilityLocked();
11008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011009 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011010
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011011 if (backgroundFillerShown == false && mBackgroundFillerShown) {
11012 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011013 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011014 try {
11015 mBackgroundFillerSurface.hide();
11016 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011017 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011018 }
11019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011021 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080011022 animating |= mDimAnimator.updateSurface(dimming, currentTime,
11023 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 }
Romain Guy06882f82009-06-10 13:36:04 -070011025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011027 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011028 + ": HIDE");
11029 try {
11030 mBlurSurface.hide();
11031 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011032 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 }
11034 mBlurShown = false;
11035 }
11036
Joe Onorato8a9b2202010-02-26 18:56:32 -080011037 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011038 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011039 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011040 }
11041
11042 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070011043
Joe Onorato8a9b2202010-02-26 18:56:32 -080011044 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011045 "With display frozen, orientationChangeComplete="
11046 + orientationChangeComplete);
11047 if (orientationChangeComplete) {
11048 if (mWindowsFreezingScreen) {
11049 mWindowsFreezingScreen = false;
11050 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
11051 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011052 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 }
Romain Guy06882f82009-06-10 13:36:04 -070011054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011055 i = mResizingWindows.size();
11056 if (i > 0) {
11057 do {
11058 i--;
11059 WindowState win = mResizingWindows.get(i);
11060 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011061 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
11062 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011063 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011064 boolean configChanged =
11065 win.mConfiguration != mCurConfiguration
11066 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011067 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
11068 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
11069 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011070 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011071 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011072 + " / " + mCurConfiguration + " / 0x"
11073 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011074 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011075 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011076 win.mClient.resized(win.mFrame.width(),
11077 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011078 win.mLastVisibleInsets, win.mDrawPending,
11079 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 win.mContentInsetsChanged = false;
11081 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011082 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011083 } catch (RemoteException e) {
11084 win.mOrientationChanging = false;
11085 }
11086 } while (i > 0);
11087 mResizingWindows.clear();
11088 }
Romain Guy06882f82009-06-10 13:36:04 -070011089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011091 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011092 i = mDestroySurface.size();
11093 if (i > 0) {
11094 do {
11095 i--;
11096 WindowState win = mDestroySurface.get(i);
11097 win.mDestroying = false;
11098 if (mInputMethodWindow == win) {
11099 mInputMethodWindow = null;
11100 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011101 if (win == mWallpaperTarget) {
11102 wallpaperDestroyed = true;
11103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 win.destroySurfaceLocked();
11105 } while (i > 0);
11106 mDestroySurface.clear();
11107 }
11108
11109 // Time to remove any exiting tokens?
11110 for (i=mExitingTokens.size()-1; i>=0; i--) {
11111 WindowToken token = mExitingTokens.get(i);
11112 if (!token.hasVisible) {
11113 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011114 if (token.windowType == TYPE_WALLPAPER) {
11115 mWallpaperTokens.remove(token);
11116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011117 }
11118 }
11119
11120 // Time to remove any exiting applications?
11121 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
11122 AppWindowToken token = mExitingAppTokens.get(i);
11123 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070011124 // Make sure there is no animation running on this token,
11125 // so any windows associated with it will be removed as
11126 // soon as their animations are complete
11127 token.animation = null;
11128 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011129 mAppTokens.remove(token);
11130 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011131 if (mLastEnterAnimToken == token) {
11132 mLastEnterAnimToken = null;
11133 mLastEnterAnimParams = null;
11134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011135 }
11136 }
11137
Dianne Hackborna8f60182009-09-01 19:01:50 -070011138 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011139
Dianne Hackborna8f60182009-09-01 19:01:50 -070011140 if (!animating && mAppTransitionRunning) {
11141 // We have finished the animation of an app transition. To do
11142 // this, we have delayed a lot of operations like showing and
11143 // hiding apps, moving apps in Z-order, etc. The app token list
11144 // reflects the correct Z-order, but the window list may now
11145 // be out of sync with it. So here we will just rebuild the
11146 // entire app window list. Fun!
11147 mAppTransitionRunning = false;
11148 needRelayout = true;
11149 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011150 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070011151 // Clear information about apps that were moving.
11152 mToBottomApps.clear();
11153 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 if (focusDisplayed) {
11156 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
11157 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011158 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011159 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011160 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011161 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011162 requestAnimationLocked(0);
11163 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011164 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
11165 }
Jeff Brown8e03b752010-06-13 19:16:55 -070011166 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 if (screenBrightness < 0 || screenBrightness > 1.0f) {
11168 mPowerManager.setScreenBrightnessOverride(-1);
11169 } else {
11170 mPowerManager.setScreenBrightnessOverride((int)
11171 (screenBrightness * Power.BRIGHTNESS_ON));
11172 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050011173 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
11174 mPowerManager.setButtonBrightnessOverride(-1);
11175 } else {
11176 mPowerManager.setButtonBrightnessOverride((int)
11177 (buttonBrightness * Power.BRIGHTNESS_ON));
11178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011179 if (holdScreen != mHoldingScreenOn) {
11180 mHoldingScreenOn = holdScreen;
11181 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
11182 mH.sendMessage(m);
11183 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011184
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011185 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011186 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011187 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
11188 LocalPowerManager.BUTTON_EVENT, true);
11189 mTurnOnScreen = false;
11190 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011191
11192 // Check to see if we are now in a state where the screen should
11193 // be enabled, because the window obscured flags have changed.
11194 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011195 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011196
11197 /**
11198 * Must be called with the main window manager lock held.
11199 */
11200 void setHoldScreenLocked(boolean holding) {
11201 boolean state = mHoldingScreenWakeLock.isHeld();
11202 if (holding != state) {
11203 if (holding) {
11204 mHoldingScreenWakeLock.acquire();
11205 } else {
11206 mPolicy.screenOnStoppedLw();
11207 mHoldingScreenWakeLock.release();
11208 }
11209 }
11210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011211
11212 void requestAnimationLocked(long delay) {
11213 if (!mAnimationPending) {
11214 mAnimationPending = true;
11215 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
11216 }
11217 }
Romain Guy06882f82009-06-10 13:36:04 -070011218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011219 /**
11220 * Have the surface flinger show a surface, robustly dealing with
11221 * error conditions. In particular, if there is not enough memory
11222 * to show the surface, then we will try to get rid of other surfaces
11223 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070011224 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011225 * @return Returns true if the surface was successfully shown.
11226 */
11227 boolean showSurfaceRobustlyLocked(WindowState win) {
11228 try {
11229 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011230 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011231 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011232 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011233 if (DEBUG_VISIBILITY) Slog.v(TAG,
11234 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011235 win.mTurnOnScreen = false;
11236 mTurnOnScreen = true;
11237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011238 }
11239 return true;
11240 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011241 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011242 }
Romain Guy06882f82009-06-10 13:36:04 -070011243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011244 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070011245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011246 return false;
11247 }
Romain Guy06882f82009-06-10 13:36:04 -070011248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011249 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
11250 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070011251
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011252 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011253 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070011254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 if (mForceRemoves == null) {
11256 mForceRemoves = new ArrayList<WindowState>();
11257 }
Romain Guy06882f82009-06-10 13:36:04 -070011258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011259 long callingIdentity = Binder.clearCallingIdentity();
11260 try {
11261 // There was some problem... first, do a sanity check of the
11262 // window list to make sure we haven't left any dangling surfaces
11263 // around.
11264 int N = mWindows.size();
11265 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011266 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011267 for (int i=0; i<N; i++) {
11268 WindowState ws = (WindowState)mWindows.get(i);
11269 if (ws.mSurface != null) {
11270 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011271 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011272 + ws + " surface=" + ws.mSurface
11273 + " token=" + win.mToken
11274 + " pid=" + ws.mSession.mPid
11275 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011276 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011277 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278 ws.mSurface = null;
11279 mForceRemoves.add(ws);
11280 i--;
11281 N--;
11282 leakedSurface = true;
11283 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011284 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 + ws + " surface=" + ws.mSurface
11286 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011287 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011288 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011289 ws.mSurface = null;
11290 leakedSurface = true;
11291 }
11292 }
11293 }
Romain Guy06882f82009-06-10 13:36:04 -070011294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011295 boolean killedApps = false;
11296 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011297 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011298 SparseIntArray pidCandidates = new SparseIntArray();
11299 for (int i=0; i<N; i++) {
11300 WindowState ws = (WindowState)mWindows.get(i);
11301 if (ws.mSurface != null) {
11302 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
11303 }
11304 }
11305 if (pidCandidates.size() > 0) {
11306 int[] pids = new int[pidCandidates.size()];
11307 for (int i=0; i<pids.length; i++) {
11308 pids[i] = pidCandidates.keyAt(i);
11309 }
11310 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070011311 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011312 killedApps = true;
11313 }
11314 } catch (RemoteException e) {
11315 }
11316 }
11317 }
Romain Guy06882f82009-06-10 13:36:04 -070011318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011319 if (leakedSurface || killedApps) {
11320 // We managed to reclaim some memory, so get rid of the trouble
11321 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011322 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011323 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011324 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011325 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011326 win.mSurface = null;
11327 }
Romain Guy06882f82009-06-10 13:36:04 -070011328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 try {
11330 win.mClient.dispatchGetNewSurface();
11331 } catch (RemoteException e) {
11332 }
11333 }
11334 } finally {
11335 Binder.restoreCallingIdentity(callingIdentity);
11336 }
11337 }
Romain Guy06882f82009-06-10 13:36:04 -070011338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 private boolean updateFocusedWindowLocked(int mode) {
11340 WindowState newFocus = computeFocusedWindowLocked();
11341 if (mCurrentFocus != newFocus) {
11342 // This check makes sure that we don't already have the focus
11343 // change message pending.
11344 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
11345 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011346 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011347 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
11348 final WindowState oldFocus = mCurrentFocus;
11349 mCurrentFocus = newFocus;
11350 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070011351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 final WindowState imWindow = mInputMethodWindow;
11353 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011354 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011355 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011356 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
11357 mLayoutNeeded = true;
11358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011359 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
11360 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011361 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
11362 // Client will do the layout, but we need to assign layers
11363 // for handleNewWindowLocked() below.
11364 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 }
11366 }
Romain Guy06882f82009-06-10 13:36:04 -070011367
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011368 if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
11369 mKeyWaiter.handleNewWindowLocked(newFocus);
11370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 return true;
11372 }
11373 return false;
11374 }
11375
11376 private WindowState computeFocusedWindowLocked() {
11377 WindowState result = null;
11378 WindowState win;
11379
11380 int i = mWindows.size() - 1;
11381 int nextAppIndex = mAppTokens.size()-1;
11382 WindowToken nextApp = nextAppIndex >= 0
11383 ? mAppTokens.get(nextAppIndex) : null;
11384
11385 while (i >= 0) {
11386 win = (WindowState)mWindows.get(i);
11387
Joe Onorato8a9b2202010-02-26 18:56:32 -080011388 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011389 TAG, "Looking for focus: " + i
11390 + " = " + win
11391 + ", flags=" + win.mAttrs.flags
11392 + ", canReceive=" + win.canReceiveKeys());
11393
11394 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011396 // If this window's application has been removed, just skip it.
11397 if (thisApp != null && thisApp.removed) {
11398 i--;
11399 continue;
11400 }
Romain Guy06882f82009-06-10 13:36:04 -070011401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011402 // If there is a focused app, don't allow focus to go to any
11403 // windows below it. If this is an application window, step
11404 // through the app tokens until we find its app.
11405 if (thisApp != null && nextApp != null && thisApp != nextApp
11406 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11407 int origAppIndex = nextAppIndex;
11408 while (nextAppIndex > 0) {
11409 if (nextApp == mFocusedApp) {
11410 // Whoops, we are below the focused app... no focus
11411 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011412 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011413 TAG, "Reached focused app: " + mFocusedApp);
11414 return null;
11415 }
11416 nextAppIndex--;
11417 nextApp = mAppTokens.get(nextAppIndex);
11418 if (nextApp == thisApp) {
11419 break;
11420 }
11421 }
11422 if (thisApp != nextApp) {
11423 // Uh oh, the app token doesn't exist! This shouldn't
11424 // happen, but if it does we can get totally hosed...
11425 // so restart at the original app.
11426 nextAppIndex = origAppIndex;
11427 nextApp = mAppTokens.get(nextAppIndex);
11428 }
11429 }
11430
11431 // Dispatch to this window if it is wants key events.
11432 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011433 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011434 TAG, "Found focus @ " + i + " = " + win);
11435 result = win;
11436 break;
11437 }
11438
11439 i--;
11440 }
11441
11442 return result;
11443 }
11444
11445 private void startFreezingDisplayLocked() {
11446 if (mDisplayFrozen) {
Chris Tate2ad63a92009-03-25 17:36:48 -070011447 // Freezing the display also suspends key event delivery, to
11448 // keep events from going astray while the display is reconfigured.
11449 // If someone has changed orientation again while the screen is
11450 // still frozen, the events will continue to be blocked while the
11451 // successive orientation change is processed. To prevent spurious
11452 // ANRs, we reset the event dispatch timeout in this case.
11453 synchronized (mKeyWaiter) {
11454 mKeyWaiter.mWasFrozen = true;
11455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011456 return;
11457 }
Romain Guy06882f82009-06-10 13:36:04 -070011458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011459 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011461 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011462 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011463 if (mFreezeGcPending != 0) {
11464 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011465 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011466 mH.removeMessages(H.FORCE_GC);
11467 Runtime.getRuntime().gc();
11468 mFreezeGcPending = now;
11469 }
11470 } else {
11471 mFreezeGcPending = now;
11472 }
Romain Guy06882f82009-06-10 13:36:04 -070011473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011474 mDisplayFrozen = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011475 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11476 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011477 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011478 mAppTransitionReady = true;
11479 }
Romain Guy06882f82009-06-10 13:36:04 -070011480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011481 if (PROFILE_ORIENTATION) {
11482 File file = new File("/data/system/frozen");
11483 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11484 }
11485 Surface.freezeDisplay(0);
11486 }
Romain Guy06882f82009-06-10 13:36:04 -070011487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011488 private void stopFreezingDisplayLocked() {
11489 if (!mDisplayFrozen) {
11490 return;
11491 }
Romain Guy06882f82009-06-10 13:36:04 -070011492
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011493 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11494 return;
11495 }
11496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011497 mDisplayFrozen = false;
11498 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11499 if (PROFILE_ORIENTATION) {
11500 Debug.stopMethodTracing();
11501 }
11502 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070011503
Chris Tate2ad63a92009-03-25 17:36:48 -070011504 // Reset the key delivery timeout on unfreeze, too. We force a wakeup here
11505 // too because regular key delivery processing should resume immediately.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011506 synchronized (mKeyWaiter) {
11507 mKeyWaiter.mWasFrozen = true;
11508 mKeyWaiter.notifyAll();
11509 }
11510
Christopher Tateb696aee2010-04-02 19:08:30 -070011511 // While the display is frozen we don't re-compute the orientation
11512 // to avoid inconsistent states. However, something interesting
11513 // could have actually changed during that time so re-evaluate it
11514 // now to catch that.
11515 if (updateOrientationFromAppTokensLocked()) {
11516 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11517 }
11518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011519 // A little kludge: a lot could have happened while the
11520 // display was frozen, so now that we are coming back we
11521 // do a gc so that any remote references the system
11522 // processes holds on others can be released if they are
11523 // no longer needed.
11524 mH.removeMessages(H.FORCE_GC);
11525 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11526 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 mScreenFrozenLock.release();
11529 }
Romain Guy06882f82009-06-10 13:36:04 -070011530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 @Override
11532 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11533 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11534 != PackageManager.PERMISSION_GRANTED) {
11535 pw.println("Permission Denial: can't dump WindowManager from from pid="
11536 + Binder.getCallingPid()
11537 + ", uid=" + Binder.getCallingUid());
11538 return;
11539 }
Romain Guy06882f82009-06-10 13:36:04 -070011540
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011541 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11542 pw.println("Input Dispatcher State:");
11543 mInputManager.dump(pw);
11544 } else {
11545 pw.println("Input State:");
11546 mQueue.dump(pw, " ");
11547 }
Dianne Hackborna2e92262010-03-02 17:19:29 -080011548 pw.println(" ");
11549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 synchronized(mWindowMap) {
11551 pw.println("Current Window Manager state:");
11552 for (int i=mWindows.size()-1; i>=0; i--) {
11553 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011554 pw.print(" Window #"); pw.print(i); pw.print(' ');
11555 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011556 w.dump(pw, " ");
11557 }
11558 if (mInputMethodDialogs.size() > 0) {
11559 pw.println(" ");
11560 pw.println(" Input method dialogs:");
11561 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11562 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011563 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 }
11565 }
11566 if (mPendingRemove.size() > 0) {
11567 pw.println(" ");
11568 pw.println(" Remove pending for:");
11569 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11570 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011571 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11572 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011573 w.dump(pw, " ");
11574 }
11575 }
11576 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11577 pw.println(" ");
11578 pw.println(" Windows force removing:");
11579 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11580 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011581 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11582 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 w.dump(pw, " ");
11584 }
11585 }
11586 if (mDestroySurface.size() > 0) {
11587 pw.println(" ");
11588 pw.println(" Windows waiting to destroy their surface:");
11589 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11590 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011591 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11592 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011593 w.dump(pw, " ");
11594 }
11595 }
11596 if (mLosingFocus.size() > 0) {
11597 pw.println(" ");
11598 pw.println(" Windows losing focus:");
11599 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11600 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011601 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11602 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011603 w.dump(pw, " ");
11604 }
11605 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011606 if (mResizingWindows.size() > 0) {
11607 pw.println(" ");
11608 pw.println(" Windows waiting to resize:");
11609 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11610 WindowState w = mResizingWindows.get(i);
11611 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11612 pw.print(w); pw.println(":");
11613 w.dump(pw, " ");
11614 }
11615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011616 if (mSessions.size() > 0) {
11617 pw.println(" ");
11618 pw.println(" All active sessions:");
11619 Iterator<Session> it = mSessions.iterator();
11620 while (it.hasNext()) {
11621 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011622 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623 s.dump(pw, " ");
11624 }
11625 }
11626 if (mTokenMap.size() > 0) {
11627 pw.println(" ");
11628 pw.println(" All tokens:");
11629 Iterator<WindowToken> it = mTokenMap.values().iterator();
11630 while (it.hasNext()) {
11631 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011632 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633 token.dump(pw, " ");
11634 }
11635 }
11636 if (mTokenList.size() > 0) {
11637 pw.println(" ");
11638 pw.println(" Window token list:");
11639 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011640 pw.print(" #"); pw.print(i); pw.print(": ");
11641 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011642 }
11643 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011644 if (mWallpaperTokens.size() > 0) {
11645 pw.println(" ");
11646 pw.println(" Wallpaper tokens:");
11647 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11648 WindowToken token = mWallpaperTokens.get(i);
11649 pw.print(" Wallpaper #"); pw.print(i);
11650 pw.print(' '); pw.print(token); pw.println(':');
11651 token.dump(pw, " ");
11652 }
11653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011654 if (mAppTokens.size() > 0) {
11655 pw.println(" ");
11656 pw.println(" Application tokens in Z order:");
11657 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011658 pw.print(" App #"); pw.print(i); pw.print(": ");
11659 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011660 }
11661 }
11662 if (mFinishedStarting.size() > 0) {
11663 pw.println(" ");
11664 pw.println(" Finishing start of application tokens:");
11665 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11666 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011667 pw.print(" Finished Starting #"); pw.print(i);
11668 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 token.dump(pw, " ");
11670 }
11671 }
11672 if (mExitingTokens.size() > 0) {
11673 pw.println(" ");
11674 pw.println(" Exiting tokens:");
11675 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11676 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011677 pw.print(" Exiting #"); pw.print(i);
11678 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 token.dump(pw, " ");
11680 }
11681 }
11682 if (mExitingAppTokens.size() > 0) {
11683 pw.println(" ");
11684 pw.println(" Exiting application tokens:");
11685 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11686 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011687 pw.print(" Exiting App #"); pw.print(i);
11688 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 token.dump(pw, " ");
11690 }
11691 }
11692 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011693 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11694 pw.print(" mLastFocus="); pw.println(mLastFocus);
11695 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11696 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11697 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011698 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011699 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11700 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11701 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11702 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011703 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11704 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11705 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011706 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11707 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11708 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11709 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011710 if (mDimAnimator != null) {
11711 mDimAnimator.printTo(pw);
11712 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011713 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011714 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011715 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011716 pw.print(mInputMethodAnimLayerAdjustment);
11717 pw.print(" mWallpaperAnimLayerAdjustment=");
11718 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011719 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11720 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011721 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11722 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011723 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11724 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011725 pw.print(" mRotation="); pw.print(mRotation);
11726 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11727 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11728 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11729 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11730 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11731 pw.print(" mNextAppTransition=0x");
11732 pw.print(Integer.toHexString(mNextAppTransition));
11733 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011734 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011735 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011736 if (mNextAppTransitionPackage != null) {
11737 pw.print(" mNextAppTransitionPackage=");
11738 pw.print(mNextAppTransitionPackage);
11739 pw.print(", mNextAppTransitionEnter=0x");
11740 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11741 pw.print(", mNextAppTransitionExit=0x");
11742 pw.print(Integer.toHexString(mNextAppTransitionExit));
11743 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011744 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11745 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011746 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11747 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11748 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11749 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011750 if (mOpeningApps.size() > 0) {
11751 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11752 }
11753 if (mClosingApps.size() > 0) {
11754 pw.print(" mClosingApps="); pw.println(mClosingApps);
11755 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011756 if (mToTopApps.size() > 0) {
11757 pw.print(" mToTopApps="); pw.println(mToTopApps);
11758 }
11759 if (mToBottomApps.size() > 0) {
11760 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11761 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011762 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11763 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011764 pw.println(" KeyWaiter state:");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011765 pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin);
11766 pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
11767 pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished);
11768 pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
11769 pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
11770 pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011771 }
11772 }
11773
11774 public void monitor() {
11775 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011776 synchronized (mKeyguardTokenWatcher) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011777 synchronized (mKeyWaiter) { }
11778 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011779
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011780 public void virtualKeyFeedback(KeyEvent event) {
11781 mPolicy.keyFeedbackFromInput(event);
11782 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011783
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011784 /**
11785 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011786 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011787 */
11788 private static class DimAnimator {
11789 Surface mDimSurface;
11790 boolean mDimShown = false;
11791 float mDimCurrentAlpha;
11792 float mDimTargetAlpha;
11793 float mDimDeltaPerMs;
11794 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011795
11796 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011797
11798 DimAnimator (SurfaceSession session) {
11799 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011800 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011801 + mDimSurface + ": CREATE");
11802 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011803 mDimSurface = new Surface(session, 0,
11804 "DimSurface",
11805 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011806 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011807 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011808 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011809 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011810 }
11811 }
11812 }
11813
11814 /**
11815 * Show the dim surface.
11816 */
11817 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011818 if (!mDimShown) {
11819 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11820 dw + "x" + dh + ")");
11821 mDimShown = true;
11822 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011823 mLastDimWidth = dw;
11824 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011825 mDimSurface.setPosition(0, 0);
11826 mDimSurface.setSize(dw, dh);
11827 mDimSurface.show();
11828 } catch (RuntimeException e) {
11829 Slog.w(TAG, "Failure showing dim surface", e);
11830 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011831 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11832 mLastDimWidth = dw;
11833 mLastDimHeight = dh;
11834 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011835 }
11836 }
11837
11838 /**
11839 * Set's the dim surface's layer and update dim parameters that will be used in
11840 * {@link updateSurface} after all windows are examined.
11841 */
11842 void updateParameters(WindowState w, long currentTime) {
11843 mDimSurface.setLayer(w.mAnimLayer-1);
11844
11845 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011846 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011847 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011848 if (mDimTargetAlpha != target) {
11849 // If the desired dim level has changed, then
11850 // start an animation to it.
11851 mLastDimAnimTime = currentTime;
11852 long duration = (w.mAnimating && w.mAnimation != null)
11853 ? w.mAnimation.computeDurationHint()
11854 : DEFAULT_DIM_DURATION;
11855 if (target > mDimTargetAlpha) {
11856 // This is happening behind the activity UI,
11857 // so we can make it run a little longer to
11858 // give a stronger impression without disrupting
11859 // the user.
11860 duration *= DIM_DURATION_MULTIPLIER;
11861 }
11862 if (duration < 1) {
11863 // Don't divide by zero
11864 duration = 1;
11865 }
11866 mDimTargetAlpha = target;
11867 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11868 }
11869 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011870
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011871 /**
11872 * Updating the surface's alpha. Returns true if the animation continues, or returns
11873 * false when the animation is finished and the dim surface is hidden.
11874 */
11875 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11876 if (!dimming) {
11877 if (mDimTargetAlpha != 0) {
11878 mLastDimAnimTime = currentTime;
11879 mDimTargetAlpha = 0;
11880 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11881 }
11882 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011883
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011884 boolean animating = false;
11885 if (mLastDimAnimTime != 0) {
11886 mDimCurrentAlpha += mDimDeltaPerMs
11887 * (currentTime-mLastDimAnimTime);
11888 boolean more = true;
11889 if (displayFrozen) {
11890 // If the display is frozen, there is no reason to animate.
11891 more = false;
11892 } else if (mDimDeltaPerMs > 0) {
11893 if (mDimCurrentAlpha > mDimTargetAlpha) {
11894 more = false;
11895 }
11896 } else if (mDimDeltaPerMs < 0) {
11897 if (mDimCurrentAlpha < mDimTargetAlpha) {
11898 more = false;
11899 }
11900 } else {
11901 more = false;
11902 }
11903
11904 // Do we need to continue animating?
11905 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011906 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011907 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11908 mLastDimAnimTime = currentTime;
11909 mDimSurface.setAlpha(mDimCurrentAlpha);
11910 animating = true;
11911 } else {
11912 mDimCurrentAlpha = mDimTargetAlpha;
11913 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011914 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011915 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11916 mDimSurface.setAlpha(mDimCurrentAlpha);
11917 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011918 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011919 + ": HIDE");
11920 try {
11921 mDimSurface.hide();
11922 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011923 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011924 }
11925 mDimShown = false;
11926 }
11927 }
11928 }
11929 return animating;
11930 }
11931
11932 public void printTo(PrintWriter pw) {
11933 pw.print(" mDimShown="); pw.print(mDimShown);
11934 pw.print(" current="); pw.print(mDimCurrentAlpha);
11935 pw.print(" target="); pw.print(mDimTargetAlpha);
11936 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11937 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11938 }
11939 }
11940
11941 /**
11942 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11943 * This is used for opening/closing transition for apps in compatible mode.
11944 */
11945 private static class FadeInOutAnimation extends Animation {
11946 int mWidth;
11947 boolean mFadeIn;
11948
11949 public FadeInOutAnimation(boolean fadeIn) {
11950 setInterpolator(new AccelerateInterpolator());
11951 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11952 mFadeIn = fadeIn;
11953 }
11954
11955 @Override
11956 protected void applyTransformation(float interpolatedTime, Transformation t) {
11957 float x = interpolatedTime;
11958 if (!mFadeIn) {
11959 x = 1.0f - x; // reverse the interpolation for fade out
11960 }
11961 if (x < 0.5) {
11962 // move the window out of the screen.
11963 t.getMatrix().setTranslate(mWidth, 0);
11964 } else {
11965 t.getMatrix().setTranslate(0, 0);// show
11966 t.setAlpha((x - 0.5f) * 2);
11967 }
11968 }
11969
11970 @Override
11971 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11972 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11973 mWidth = width;
11974 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011975
11976 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011977 public int getZAdjustment() {
11978 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011979 }
11980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011981}