blob: 9bc3931290e469106ccc7d3f06b198fc0b8a08ed [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;
Dianne Hackbornce73c1e2010-04-12 23:11:38 -0700159 static final boolean DEBUG_FREEZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700161 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700162 static final boolean MEASURE_LATENCY = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700163 static final boolean ENABLE_NATIVE_INPUT_DISPATCH =
164 WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH;
Michael Chan53071d62009-05-13 17:29:48 -0700165 static private LatencyTimer lt;
166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 static final boolean PROFILE_ORIENTATION = false;
168 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700169 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 /** How long to wait for subsequent key repeats, in milliseconds */
172 static final int KEY_REPEAT_DELAY = 50;
173
174 /** How much to multiply the policy's type layer, to reserve room
175 * for multiple windows of the same type and Z-ordering adjustment
176 * with TYPE_LAYER_OFFSET. */
177 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
180 * or below others in the same layer. */
181 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /** How much to increment the layer for each window, to reserve room
184 * for effect surfaces between them.
185 */
186 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 /** The maximum length we will accept for a loaded animation duration:
189 * this is 10 seconds.
190 */
191 static final int MAX_ANIMATION_DURATION = 10*1000;
192
193 /** Amount of time (in milliseconds) to animate the dim surface from one
194 * value to another, when no window animation is driving it.
195 */
196 static final int DEFAULT_DIM_DURATION = 200;
197
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700198 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
199 * compatible windows.
200 */
201 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /** Adjustment to time to perform a dim, to make it more dramatic.
204 */
205 static final int DIM_DURATION_MULTIPLIER = 6;
Romain Guy06882f82009-06-10 13:36:04 -0700206
Dianne Hackborncfaef692009-06-15 14:24:44 -0700207 static final int INJECT_FAILED = 0;
208 static final int INJECT_SUCCEEDED = 1;
209 static final int INJECT_NO_PERMISSION = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 static final int UPDATE_FOCUS_NORMAL = 0;
212 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
213 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
214 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700215
Michael Chane96440f2009-05-06 10:27:36 -0700216 /** The minimum time between dispatching touch events. */
217 int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
218
219 // Last touch event time
220 long mLastTouchEventTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700221
Michael Chane96440f2009-05-06 10:27:36 -0700222 // Last touch event type
223 int mLastTouchEventType = OTHER_EVENT;
Romain Guy06882f82009-06-10 13:36:04 -0700224
Michael Chane96440f2009-05-06 10:27:36 -0700225 // Time to wait before calling useractivity again. This saves CPU usage
226 // when we get a flood of touch events.
227 static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
228
229 // Last time we call user activity
230 long mLastUserActivityCallTime = 0;
231
Romain Guy06882f82009-06-10 13:36:04 -0700232 // Last time we updated battery stats
Michael Chane96440f2009-05-06 10:27:36 -0700233 long mLastBatteryStatsCallTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700236 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237
238 /**
239 * Condition waited on by {@link #reenableKeyguard} to know the call to
240 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500241 * This is set to true only if mKeyguardTokenWatcher.acquired() has
242 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500244 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
Jim Miller284b62e2010-06-08 14:27:42 -0700246 private static final int ALLOW_DISABLE_YES = 1;
247 private static final int ALLOW_DISABLE_NO = 0;
248 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
249 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
250
Mike Lockwood983ee092009-11-22 01:42:24 -0500251 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
252 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700254 if (shouldAllowDisableKeyguard()) {
255 mPolicy.enableKeyguard(false);
256 mKeyguardDisabled = true;
257 } else {
258 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
261 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700262 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500263 synchronized (mKeyguardTokenWatcher) {
264 mKeyguardDisabled = false;
265 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 }
267 }
268 };
269
Jim Miller284b62e2010-06-08 14:27:42 -0700270 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
271 @Override
272 public void onReceive(Context context, Intent intent) {
273 mPolicy.enableKeyguard(true);
274 synchronized(mKeyguardTokenWatcher) {
275 // lazily evaluate this next time we're asked to disable keyguard
276 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
277 mKeyguardDisabled = false;
278 }
279 }
280 };
281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 final Context mContext;
283
284 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
289
290 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 /**
295 * All currently active sessions with clients.
296 */
297 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 /**
300 * Mapping from an IWindow IBinder to the server's Window object.
301 * This is also used as the lock for all of our state.
302 */
303 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
304
305 /**
306 * Mapping from a token IBinder to a WindowToken object.
307 */
308 final HashMap<IBinder, WindowToken> mTokenMap =
309 new HashMap<IBinder, WindowToken>();
310
311 /**
312 * The same tokens as mTokenMap, stored in a list for efficient iteration
313 * over them.
314 */
315 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 /**
318 * Window tokens that are in the process of exiting, but still
319 * on screen for animations.
320 */
321 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
322
323 /**
324 * Z-ordered (bottom-most first) list of all application tokens, for
325 * controlling the ordering of windows in different applications. This
326 * contains WindowToken objects.
327 */
328 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
329
330 /**
331 * Application tokens that are in the process of exiting, but still
332 * on screen for animations.
333 */
334 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
335
336 /**
337 * List of window tokens that have finished starting their application,
338 * and now need to have the policy remove their windows.
339 */
340 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
341
342 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700343 * This was the app token that was used to retrieve the last enter
344 * animation. It will be used for the next exit animation.
345 */
346 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800347
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700348 /**
349 * These were the layout params used to retrieve the last enter animation.
350 * They will be used for the next exit animation.
351 */
352 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800353
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700354 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 * Z-ordered (bottom-most first) list of all Window objects.
356 */
357 final ArrayList mWindows = new ArrayList();
358
359 /**
360 * Windows that are being resized. Used so we can tell the client about
361 * the resize after closing the transaction in which we resized the
362 * underlying surface.
363 */
364 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
365
366 /**
367 * Windows whose animations have ended and now must be removed.
368 */
369 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
370
371 /**
372 * Windows whose surface should be destroyed.
373 */
374 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
375
376 /**
377 * Windows that have lost input focus and are waiting for the new
378 * focus window to be displayed before they are told about this.
379 */
380 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
381
382 /**
383 * This is set when we have run out of memory, and will either be an empty
384 * list or contain windows that need to be force removed.
385 */
386 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700391 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 Surface mBlurSurface;
393 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 final float[] mTmpFloats = new float[9];
398
399 boolean mSafeMode;
400 boolean mDisplayEnabled = false;
401 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700402 int mInitialDisplayWidth = 0;
403 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 int mRotation = 0;
405 int mRequestedRotation = 0;
406 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700407 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 ArrayList<IRotationWatcher> mRotationWatchers
409 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 boolean mLayoutNeeded = true;
412 boolean mAnimationPending = false;
413 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800414 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 boolean mWindowsFreezingScreen = false;
416 long mFreezeGcPending = 0;
417 int mAppsFreezingScreen = 0;
418
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800419 int mLayoutSeq = 0;
420
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800421 // State while inside of layoutAndPlaceSurfacesLocked().
422 boolean mFocusMayChange;
423
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800424 Configuration mCurConfiguration = new Configuration();
425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 // This is held as long as we have the screen frozen, to give us time to
427 // perform a rotation animation when turning off shows the lock screen which
428 // changes the orientation.
429 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 // State management of app transitions. When we are preparing for a
432 // transition, mNextAppTransition will be the kind of transition to
433 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
434 // mOpeningApps and mClosingApps are the lists of tokens that will be
435 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700436 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700437 String mNextAppTransitionPackage;
438 int mNextAppTransitionEnter;
439 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700441 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 boolean mAppTransitionTimeout = false;
443 boolean mStartingIconInTransition = false;
444 boolean mSkipAppTransitionAnimation = false;
445 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
446 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700447 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
448 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 //flag to detect fat touch events
451 boolean mFatTouch = false;
452 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 H mH = new H();
455
456 WindowState mCurrentFocus = null;
457 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 // This just indicates the window the input method is on top of, not
460 // necessarily the window its input is going to.
461 WindowState mInputMethodTarget = null;
462 WindowState mUpcomingInputMethodTarget = null;
463 boolean mInputMethodTargetWaitingAnim;
464 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 WindowState mInputMethodWindow = null;
467 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
468
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700469 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800470
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700471 // If non-null, this is the currently visible window that is associated
472 // with the wallpaper.
473 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700474 // If non-null, we are in the middle of animating from one wallpaper target
475 // to another, and this is the lower one in Z-order.
476 WindowState mLowerWallpaperTarget = null;
477 // If non-null, we are in the middle of animating from one wallpaper target
478 // to another, and this is the higher one in Z-order.
479 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700480 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700481 float mLastWallpaperX = -1;
482 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800483 float mLastWallpaperXStep = -1;
484 float mLastWallpaperYStep = -1;
Dianne Hackborn6adba242009-11-10 11:10:09 -0800485 boolean mSendingPointersToWallpaper = false;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700486 // This is set when we are waiting for a wallpaper to tell us it is done
487 // changing its scroll position.
488 WindowState mWaitingOnWallpaper;
489 // The last time we had a timeout when waiting for a wallpaper.
490 long mLastWallpaperTimeoutTime;
491 // We give a wallpaper up to 150ms to finish scrolling.
492 static final long WALLPAPER_TIMEOUT = 150;
493 // Time we wait after a timeout before trying to wait again.
494 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 AppWindowToken mFocusedApp = null;
497
498 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 float mWindowAnimationScale = 1.0f;
501 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 final KeyWaiter mKeyWaiter = new KeyWaiter();
504 final KeyQ mQueue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700505 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 final InputDispatcherThread mInputThread;
507
508 // Who is holding the screen on.
509 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700510 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700511
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700512 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 /**
515 * Whether the UI is currently running in touch mode (not showing
516 * navigational focus because the user is directly pressing the screen).
517 */
518 boolean mInTouchMode = false;
519
520 private ViewServer mViewServer;
521
522 final Rect mTempRect = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -0700523
Dianne Hackbornc485a602009-03-24 22:39:49 -0700524 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700525 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700526
527 // The frame use to limit the size of the app running in compatibility mode.
528 Rect mCompatibleScreenFrame = new Rect();
529 // The surface used to fill the outer rim of the app running in compatibility mode.
530 Surface mBackgroundFillerSurface = null;
531 boolean mBackgroundFillerShown = false;
532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 public static WindowManagerService main(Context context,
534 PowerManagerService pm, boolean haveInputMethods) {
535 WMThread thr = new WMThread(context, pm, haveInputMethods);
536 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 synchronized (thr) {
539 while (thr.mService == null) {
540 try {
541 thr.wait();
542 } catch (InterruptedException e) {
543 }
544 }
545 }
Romain Guy06882f82009-06-10 13:36:04 -0700546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 return thr.mService;
548 }
Romain Guy06882f82009-06-10 13:36:04 -0700549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 static class WMThread extends Thread {
551 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 private final Context mContext;
554 private final PowerManagerService mPM;
555 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 public WMThread(Context context, PowerManagerService pm,
558 boolean haveInputMethods) {
559 super("WindowManager");
560 mContext = context;
561 mPM = pm;
562 mHaveInputMethods = haveInputMethods;
563 }
Romain Guy06882f82009-06-10 13:36:04 -0700564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 public void run() {
566 Looper.prepare();
567 WindowManagerService s = new WindowManagerService(mContext, mPM,
568 mHaveInputMethods);
569 android.os.Process.setThreadPriority(
570 android.os.Process.THREAD_PRIORITY_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -0700571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 synchronized (this) {
573 mService = s;
574 notifyAll();
575 }
Romain Guy06882f82009-06-10 13:36:04 -0700576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 Looper.loop();
578 }
579 }
580
581 static class PolicyThread extends Thread {
582 private final WindowManagerPolicy mPolicy;
583 private final WindowManagerService mService;
584 private final Context mContext;
585 private final PowerManagerService mPM;
586 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 public PolicyThread(WindowManagerPolicy policy,
589 WindowManagerService service, Context context,
590 PowerManagerService pm) {
591 super("WindowManagerPolicy");
592 mPolicy = policy;
593 mService = service;
594 mContext = context;
595 mPM = pm;
596 }
Romain Guy06882f82009-06-10 13:36:04 -0700597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 public void run() {
599 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800600 WindowManagerPolicyThread.set(this, Looper.myLooper());
601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800603 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 android.os.Process.setThreadPriority(
605 android.os.Process.THREAD_PRIORITY_FOREGROUND);
606 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 synchronized (this) {
609 mRunning = true;
610 notifyAll();
611 }
Romain Guy06882f82009-06-10 13:36:04 -0700612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 Looper.loop();
614 }
615 }
616
617 private WindowManagerService(Context context, PowerManagerService pm,
618 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700619 if (MEASURE_LATENCY) {
620 lt = new LatencyTimer(100, 1000);
621 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 mContext = context;
624 mHaveInputMethods = haveInputMethods;
625 mLimitedAlphaCompositing = context.getResources().getBoolean(
626 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 mPowerManager = pm;
629 mPowerManager.setPolicy(mPolicy);
630 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
631 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
632 "SCREEN_FROZEN");
633 mScreenFrozenLock.setReferenceCounted(false);
634
635 mActivityManager = ActivityManagerNative.getDefault();
636 mBatteryStats = BatteryStatsService.getService();
637
638 // Get persisted window scale setting
639 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
640 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
641 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
642 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700643
Jim Miller284b62e2010-06-08 14:27:42 -0700644 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
645 IntentFilter filter = new IntentFilter();
646 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
647 mContext.registerReceiver(mBroadcastReceiver, filter);
648
Michael Chan9f028e62009-08-04 17:37:46 -0700649 int max_events_per_sec = 35;
650 try {
651 max_events_per_sec = Integer.parseInt(SystemProperties
652 .get("windowsmgr.max_events_per_sec"));
653 if (max_events_per_sec < 1) {
654 max_events_per_sec = 35;
655 }
656 } catch (NumberFormatException e) {
657 }
658 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
659
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700660 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
661 "KEEP_SCREEN_ON_FLAG");
662 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700664 if (ENABLE_NATIVE_INPUT_DISPATCH) {
665 mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager);
666 } else {
667 mInputManager = null;
668 }
669 mQueue = new KeyQ();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 mInputThread = new InputDispatcherThread();
Romain Guy06882f82009-06-10 13:36:04 -0700671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
673 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 synchronized (thr) {
676 while (!thr.mRunning) {
677 try {
678 thr.wait();
679 } catch (InterruptedException e) {
680 }
681 }
682 }
Romain Guy06882f82009-06-10 13:36:04 -0700683
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700684 if (ENABLE_NATIVE_INPUT_DISPATCH) {
685 mInputManager.start();
686 } else {
687 mInputThread.start();
688 }
Romain Guy06882f82009-06-10 13:36:04 -0700689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 // Add ourself to the Watchdog monitors.
691 Watchdog.getInstance().addMonitor(this);
692 }
693
694 @Override
695 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
696 throws RemoteException {
697 try {
698 return super.onTransact(code, data, reply, flags);
699 } catch (RuntimeException e) {
700 // The window manager only throws security exceptions, so let's
701 // log all others.
702 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800703 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 }
705 throw e;
706 }
707 }
708
709 private void placeWindowAfter(Object pos, WindowState window) {
710 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800711 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 TAG, "Adding window " + window + " at "
713 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
714 mWindows.add(i+1, window);
715 }
716
717 private void placeWindowBefore(Object pos, WindowState window) {
718 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800719 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 TAG, "Adding window " + window + " at "
721 + i + " of " + mWindows.size() + " (before " + pos + ")");
722 mWindows.add(i, window);
723 }
724
725 //This method finds out the index of a window that has the same app token as
726 //win. used for z ordering the windows in mWindows
727 private int findIdxBasedOnAppTokens(WindowState win) {
728 //use a local variable to cache mWindows
729 ArrayList localmWindows = mWindows;
730 int jmax = localmWindows.size();
731 if(jmax == 0) {
732 return -1;
733 }
734 for(int j = (jmax-1); j >= 0; j--) {
735 WindowState wentry = (WindowState)localmWindows.get(j);
736 if(wentry.mAppToken == win.mAppToken) {
737 return j;
738 }
739 }
740 return -1;
741 }
Romain Guy06882f82009-06-10 13:36:04 -0700742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
744 final IWindow client = win.mClient;
745 final WindowToken token = win.mToken;
746 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 final int N = localmWindows.size();
749 final WindowState attached = win.mAttachedWindow;
750 int i;
751 if (attached == null) {
752 int tokenWindowsPos = token.windows.size();
753 if (token.appWindowToken != null) {
754 int index = tokenWindowsPos-1;
755 if (index >= 0) {
756 // If this application has existing windows, we
757 // simply place the new window on top of them... but
758 // keep the starting window on top.
759 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
760 // Base windows go behind everything else.
761 placeWindowBefore(token.windows.get(0), win);
762 tokenWindowsPos = 0;
763 } else {
764 AppWindowToken atoken = win.mAppToken;
765 if (atoken != null &&
766 token.windows.get(index) == atoken.startingWindow) {
767 placeWindowBefore(token.windows.get(index), win);
768 tokenWindowsPos--;
769 } else {
770 int newIdx = findIdxBasedOnAppTokens(win);
771 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700772 //there is a window above this one associated with the same
773 //apptoken note that the window could be a floating window
774 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800776 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700777 TAG, "Adding window " + win + " at "
778 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 localmWindows.add(newIdx+1, win);
Romain Guy06882f82009-06-10 13:36:04 -0700780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 }
782 }
783 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800784 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 TAG, "Figuring out where to add app window "
786 + client.asBinder() + " (token=" + token + ")");
787 // Figure out where the window should go, based on the
788 // order of applications.
789 final int NA = mAppTokens.size();
790 Object pos = null;
791 for (i=NA-1; i>=0; i--) {
792 AppWindowToken t = mAppTokens.get(i);
793 if (t == token) {
794 i--;
795 break;
796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800797
Dianne Hackborna8f60182009-09-01 19:01:50 -0700798 // We haven't reached the token yet; if this token
799 // is not going to the bottom and has windows, we can
800 // use it as an anchor for when we do reach the token.
801 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 pos = t.windows.get(0);
803 }
804 }
805 // We now know the index into the apps. If we found
806 // an app window above, that gives us the position; else
807 // we need to look some more.
808 if (pos != null) {
809 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700810 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 mTokenMap.get(((WindowState)pos).mClient.asBinder());
812 if (atoken != null) {
813 final int NC = atoken.windows.size();
814 if (NC > 0) {
815 WindowState bottom = atoken.windows.get(0);
816 if (bottom.mSubLayer < 0) {
817 pos = bottom;
818 }
819 }
820 }
821 placeWindowBefore(pos, win);
822 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700823 // Continue looking down until we find the first
824 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 while (i >= 0) {
826 AppWindowToken t = mAppTokens.get(i);
827 final int NW = t.windows.size();
828 if (NW > 0) {
829 pos = t.windows.get(NW-1);
830 break;
831 }
832 i--;
833 }
834 if (pos != null) {
835 // Move in front of any windows attached to this
836 // one.
837 WindowToken atoken =
838 mTokenMap.get(((WindowState)pos).mClient.asBinder());
839 if (atoken != null) {
840 final int NC = atoken.windows.size();
841 if (NC > 0) {
842 WindowState top = atoken.windows.get(NC-1);
843 if (top.mSubLayer >= 0) {
844 pos = top;
845 }
846 }
847 }
848 placeWindowAfter(pos, win);
849 } else {
850 // Just search for the start of this layer.
851 final int myLayer = win.mBaseLayer;
852 for (i=0; i<N; i++) {
853 WindowState w = (WindowState)localmWindows.get(i);
854 if (w.mBaseLayer > myLayer) {
855 break;
856 }
857 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800858 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700859 TAG, "Adding window " + win + " at "
860 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 localmWindows.add(i, win);
862 }
863 }
864 }
865 } else {
866 // Figure out where window should go, based on layer.
867 final int myLayer = win.mBaseLayer;
868 for (i=N-1; i>=0; i--) {
869 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
870 i++;
871 break;
872 }
873 }
874 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800875 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700876 TAG, "Adding window " + win + " at "
877 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 localmWindows.add(i, win);
879 }
880 if (addToToken) {
881 token.windows.add(tokenWindowsPos, win);
882 }
883
884 } else {
885 // Figure out this window's ordering relative to the window
886 // it is attached to.
887 final int NA = token.windows.size();
888 final int sublayer = win.mSubLayer;
889 int largestSublayer = Integer.MIN_VALUE;
890 WindowState windowWithLargestSublayer = null;
891 for (i=0; i<NA; i++) {
892 WindowState w = token.windows.get(i);
893 final int wSublayer = w.mSubLayer;
894 if (wSublayer >= largestSublayer) {
895 largestSublayer = wSublayer;
896 windowWithLargestSublayer = w;
897 }
898 if (sublayer < 0) {
899 // For negative sublayers, we go below all windows
900 // in the same sublayer.
901 if (wSublayer >= sublayer) {
902 if (addToToken) {
903 token.windows.add(i, win);
904 }
905 placeWindowBefore(
906 wSublayer >= 0 ? attached : w, win);
907 break;
908 }
909 } else {
910 // For positive sublayers, we go above all windows
911 // in the same sublayer.
912 if (wSublayer > sublayer) {
913 if (addToToken) {
914 token.windows.add(i, win);
915 }
916 placeWindowBefore(w, win);
917 break;
918 }
919 }
920 }
921 if (i >= NA) {
922 if (addToToken) {
923 token.windows.add(win);
924 }
925 if (sublayer < 0) {
926 placeWindowBefore(attached, win);
927 } else {
928 placeWindowAfter(largestSublayer >= 0
929 ? windowWithLargestSublayer
930 : attached,
931 win);
932 }
933 }
934 }
Romain Guy06882f82009-06-10 13:36:04 -0700935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 if (win.mAppToken != null && addToToken) {
937 win.mAppToken.allAppWindows.add(win);
938 }
939 }
Romain Guy06882f82009-06-10 13:36:04 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 static boolean canBeImeTarget(WindowState w) {
942 final int fl = w.mAttrs.flags
943 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
944 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
945 return w.isVisibleOrAdding();
946 }
947 return false;
948 }
Romain Guy06882f82009-06-10 13:36:04 -0700949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
951 final ArrayList localmWindows = mWindows;
952 final int N = localmWindows.size();
953 WindowState w = null;
954 int i = N;
955 while (i > 0) {
956 i--;
957 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700958
Joe Onorato8a9b2202010-02-26 18:56:32 -0800959 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 // + Integer.toHexString(w.mAttrs.flags));
961 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800962 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 // Yet more tricksyness! If this window is a "starting"
965 // window, we do actually want to be on top of it, but
966 // it is not -really- where input will go. So if the caller
967 // is not actually looking to move the IME, look down below
968 // for a real window to target...
969 if (!willMove
970 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
971 && i > 0) {
972 WindowState wb = (WindowState)localmWindows.get(i-1);
973 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
974 i--;
975 w = wb;
976 }
977 }
978 break;
979 }
980 }
Romain Guy06882f82009-06-10 13:36:04 -0700981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700983
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 if (willMove && w != null) {
988 final WindowState curTarget = mInputMethodTarget;
989 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 // Now some fun for dealing with window animations that
992 // modify the Z order. We need to look at all windows below
993 // the current target that are in this app, finding the highest
994 // visible one in layering.
995 AppWindowToken token = curTarget.mAppToken;
996 WindowState highestTarget = null;
997 int highestPos = 0;
998 if (token.animating || token.animation != null) {
999 int pos = 0;
1000 pos = localmWindows.indexOf(curTarget);
1001 while (pos >= 0) {
1002 WindowState win = (WindowState)localmWindows.get(pos);
1003 if (win.mAppToken != token) {
1004 break;
1005 }
1006 if (!win.mRemoved) {
1007 if (highestTarget == null || win.mAnimLayer >
1008 highestTarget.mAnimLayer) {
1009 highestTarget = win;
1010 highestPos = pos;
1011 }
1012 }
1013 pos--;
1014 }
1015 }
Romain Guy06882f82009-06-10 13:36:04 -07001016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001018 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 + mNextAppTransition + " " + highestTarget
1020 + " animating=" + highestTarget.isAnimating()
1021 + " layer=" + highestTarget.mAnimLayer
1022 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001023
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001024 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 // If we are currently setting up for an animation,
1026 // hold everything until we can find out what will happen.
1027 mInputMethodTargetWaitingAnim = true;
1028 mInputMethodTarget = highestTarget;
1029 return highestPos + 1;
1030 } else if (highestTarget.isAnimating() &&
1031 highestTarget.mAnimLayer > w.mAnimLayer) {
1032 // If the window we are currently targeting is involved
1033 // with an animation, and it is on top of the next target
1034 // we will be over, then hold off on moving until
1035 // that is done.
1036 mInputMethodTarget = highestTarget;
1037 return highestPos + 1;
1038 }
1039 }
1040 }
1041 }
Romain Guy06882f82009-06-10 13:36:04 -07001042
Joe Onorato8a9b2202010-02-26 18:56:32 -08001043 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 if (w != null) {
1045 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001046 if (DEBUG_INPUT_METHOD) {
1047 RuntimeException e = null;
1048 if (!HIDE_STACK_CRAWLS) {
1049 e = new RuntimeException();
1050 e.fillInStackTrace();
1051 }
1052 Slog.w(TAG, "Moving IM target from "
1053 + mInputMethodTarget + " to " + w, e);
1054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 mInputMethodTarget = w;
1056 if (w.mAppToken != null) {
1057 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1058 } else {
1059 setInputMethodAnimLayerAdjustment(0);
1060 }
1061 }
1062 return i+1;
1063 }
1064 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001065 if (DEBUG_INPUT_METHOD) {
1066 RuntimeException e = null;
1067 if (!HIDE_STACK_CRAWLS) {
1068 e = new RuntimeException();
1069 e.fillInStackTrace();
1070 }
1071 Slog.w(TAG, "Moving IM target from "
1072 + mInputMethodTarget + " to null", e);
1073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 mInputMethodTarget = null;
1075 setInputMethodAnimLayerAdjustment(0);
1076 }
1077 return -1;
1078 }
Romain Guy06882f82009-06-10 13:36:04 -07001079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 void addInputMethodWindowToListLocked(WindowState win) {
1081 int pos = findDesiredInputMethodWindowIndexLocked(true);
1082 if (pos >= 0) {
1083 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001084 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001085 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 mWindows.add(pos, win);
1087 moveInputMethodDialogsLocked(pos+1);
1088 return;
1089 }
1090 win.mTargetAppToken = null;
1091 addWindowToListInOrderLocked(win, true);
1092 moveInputMethodDialogsLocked(pos);
1093 }
Romain Guy06882f82009-06-10 13:36:04 -07001094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001096 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 mInputMethodAnimLayerAdjustment = adj;
1098 WindowState imw = mInputMethodWindow;
1099 if (imw != null) {
1100 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001101 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 + " anim layer: " + imw.mAnimLayer);
1103 int wi = imw.mChildWindows.size();
1104 while (wi > 0) {
1105 wi--;
1106 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1107 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001108 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 + " anim layer: " + cw.mAnimLayer);
1110 }
1111 }
1112 int di = mInputMethodDialogs.size();
1113 while (di > 0) {
1114 di --;
1115 imw = mInputMethodDialogs.get(di);
1116 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001117 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 + " anim layer: " + imw.mAnimLayer);
1119 }
1120 }
Romain Guy06882f82009-06-10 13:36:04 -07001121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1123 int wpos = mWindows.indexOf(win);
1124 if (wpos >= 0) {
1125 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001126 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 mWindows.remove(wpos);
1128 int NC = win.mChildWindows.size();
1129 while (NC > 0) {
1130 NC--;
1131 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1132 int cpos = mWindows.indexOf(cw);
1133 if (cpos >= 0) {
1134 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001135 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001136 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 mWindows.remove(cpos);
1138 }
1139 }
1140 }
1141 return interestingPos;
1142 }
Romain Guy06882f82009-06-10 13:36:04 -07001143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 private void reAddWindowToListInOrderLocked(WindowState win) {
1145 addWindowToListInOrderLocked(win, false);
1146 // This is a hack to get all of the child windows added as well
1147 // at the right position. Child windows should be rare and
1148 // this case should be rare, so it shouldn't be that big a deal.
1149 int wpos = mWindows.indexOf(win);
1150 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001151 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001152 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 mWindows.remove(wpos);
1154 reAddWindowLocked(wpos, win);
1155 }
1156 }
Romain Guy06882f82009-06-10 13:36:04 -07001157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 void logWindowList(String prefix) {
1159 int N = mWindows.size();
1160 while (N > 0) {
1161 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001162 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 }
1164 }
Romain Guy06882f82009-06-10 13:36:04 -07001165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 void moveInputMethodDialogsLocked(int pos) {
1167 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001170 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 for (int i=0; i<N; i++) {
1172 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1173 }
1174 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001175 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 logWindowList(" ");
1177 }
Romain Guy06882f82009-06-10 13:36:04 -07001178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179 if (pos >= 0) {
1180 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1181 if (pos < mWindows.size()) {
1182 WindowState wp = (WindowState)mWindows.get(pos);
1183 if (wp == mInputMethodWindow) {
1184 pos++;
1185 }
1186 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001187 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 for (int i=0; i<N; i++) {
1189 WindowState win = dialogs.get(i);
1190 win.mTargetAppToken = targetAppToken;
1191 pos = reAddWindowLocked(pos, win);
1192 }
1193 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001194 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 logWindowList(" ");
1196 }
1197 return;
1198 }
1199 for (int i=0; i<N; i++) {
1200 WindowState win = dialogs.get(i);
1201 win.mTargetAppToken = null;
1202 reAddWindowToListInOrderLocked(win);
1203 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001204 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 logWindowList(" ");
1206 }
1207 }
1208 }
Romain Guy06882f82009-06-10 13:36:04 -07001209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1211 final WindowState imWin = mInputMethodWindow;
1212 final int DN = mInputMethodDialogs.size();
1213 if (imWin == null && DN == 0) {
1214 return false;
1215 }
Romain Guy06882f82009-06-10 13:36:04 -07001216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1218 if (imPos >= 0) {
1219 // In this case, the input method windows are to be placed
1220 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 // First check to see if the input method windows are already
1223 // located here, and contiguous.
1224 final int N = mWindows.size();
1225 WindowState firstImWin = imPos < N
1226 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 // Figure out the actual input method window that should be
1229 // at the bottom of their stack.
1230 WindowState baseImWin = imWin != null
1231 ? imWin : mInputMethodDialogs.get(0);
1232 if (baseImWin.mChildWindows.size() > 0) {
1233 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1234 if (cw.mSubLayer < 0) baseImWin = cw;
1235 }
Romain Guy06882f82009-06-10 13:36:04 -07001236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 if (firstImWin == baseImWin) {
1238 // The windows haven't moved... but are they still contiguous?
1239 // First find the top IM window.
1240 int pos = imPos+1;
1241 while (pos < N) {
1242 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1243 break;
1244 }
1245 pos++;
1246 }
1247 pos++;
1248 // Now there should be no more input method windows above.
1249 while (pos < N) {
1250 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1251 break;
1252 }
1253 pos++;
1254 }
1255 if (pos >= N) {
1256 // All is good!
1257 return false;
1258 }
1259 }
Romain Guy06882f82009-06-10 13:36:04 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 if (imWin != null) {
1262 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001263 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 logWindowList(" ");
1265 }
1266 imPos = tmpRemoveWindowLocked(imPos, imWin);
1267 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001268 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 logWindowList(" ");
1270 }
1271 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1272 reAddWindowLocked(imPos, imWin);
1273 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001274 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 logWindowList(" ");
1276 }
1277 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1278 } else {
1279 moveInputMethodDialogsLocked(imPos);
1280 }
Romain Guy06882f82009-06-10 13:36:04 -07001281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 } else {
1283 // In this case, the input method windows go in a fixed layer,
1284 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001287 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 tmpRemoveWindowLocked(0, imWin);
1289 imWin.mTargetAppToken = null;
1290 reAddWindowToListInOrderLocked(imWin);
1291 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001292 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 logWindowList(" ");
1294 }
1295 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1296 } else {
1297 moveInputMethodDialogsLocked(-1);;
1298 }
Romain Guy06882f82009-06-10 13:36:04 -07001299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 }
Romain Guy06882f82009-06-10 13:36:04 -07001301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 if (needAssignLayers) {
1303 assignLayersLocked();
1304 }
Romain Guy06882f82009-06-10 13:36:04 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 return true;
1307 }
Romain Guy06882f82009-06-10 13:36:04 -07001308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 void adjustInputMethodDialogsLocked() {
1310 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1311 }
Romain Guy06882f82009-06-10 13:36:04 -07001312
Dianne Hackborn25994b42009-09-04 14:21:19 -07001313 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001314 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001315 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1316 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1317 ? wallpaperTarget.mAppToken.animation : null)
1318 + " upper=" + mUpperWallpaperTarget
1319 + " lower=" + mLowerWallpaperTarget);
1320 return (wallpaperTarget != null
1321 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1322 && wallpaperTarget.mAppToken.animation != null)))
1323 || mUpperWallpaperTarget != null
1324 || mLowerWallpaperTarget != null;
1325 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001326
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001327 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1328 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001329
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001330 int adjustWallpaperWindowsLocked() {
1331 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001332
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001333 final int dw = mDisplay.getWidth();
1334 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001335
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001336 // First find top-most window that has asked to be on top of the
1337 // wallpaper; all wallpapers go behind it.
1338 final ArrayList localmWindows = mWindows;
1339 int N = localmWindows.size();
1340 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001341 WindowState foundW = null;
1342 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001343 WindowState topCurW = null;
1344 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001345 int i = N;
1346 while (i > 0) {
1347 i--;
1348 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001349 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1350 if (topCurW == null) {
1351 topCurW = w;
1352 topCurI = i;
1353 }
1354 continue;
1355 }
1356 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001357 if (w.mAppToken != null) {
1358 // If this window's app token is hidden and not animating,
1359 // it is of no interest to us.
1360 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001361 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001362 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001363 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001364 continue;
1365 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001366 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001367 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001368 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1369 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001370 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001371 && (mWallpaperTarget == w
1372 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001373 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001374 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001375 foundW = w;
1376 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001377 if (w == mWallpaperTarget && ((w.mAppToken != null
1378 && w.mAppToken.animation != null)
1379 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001380 // The current wallpaper target is animating, so we'll
1381 // look behind it for another possible target and figure
1382 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001383 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001384 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001385 continue;
1386 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001387 break;
1388 }
1389 }
1390
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001391 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001392 // If we are currently waiting for an app transition, and either
1393 // the current target or the next target are involved with it,
1394 // then hold off on doing anything with the wallpaper.
1395 // Note that we are checking here for just whether the target
1396 // is part of an app token... which is potentially overly aggressive
1397 // (the app token may not be involved in the transition), but good
1398 // enough (we'll just wait until whatever transition is pending
1399 // executes).
1400 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001401 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001402 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001403 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001404 }
1405 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001406 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001407 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001408 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001409 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001411
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001412 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001413 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001414 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001415 + " oldTarget: " + mWallpaperTarget);
1416 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001417
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001418 mLowerWallpaperTarget = null;
1419 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001420
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001421 WindowState oldW = mWallpaperTarget;
1422 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001423
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001424 // Now what is happening... if the current and new targets are
1425 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001426 if (foundW != null && oldW != null) {
1427 boolean oldAnim = oldW.mAnimation != null
1428 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1429 boolean foundAnim = foundW.mAnimation != null
1430 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001431 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001432 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001433 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001434 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001435 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001436 int oldI = localmWindows.indexOf(oldW);
1437 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001438 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001439 }
1440 if (oldI >= 0) {
1441 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001442 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001443 + "=" + oldW + "; new#" + foundI
1444 + "=" + foundW);
1445 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001446
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001447 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001448 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001449 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001451 }
1452 mWallpaperTarget = oldW;
1453 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001454
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001455 // Now set the upper and lower wallpaper targets
1456 // correctly, and make sure that we are positioning
1457 // the wallpaper below the lower.
1458 if (foundI > oldI) {
1459 // The new target is on top of the old one.
1460 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001461 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001462 }
1463 mUpperWallpaperTarget = foundW;
1464 mLowerWallpaperTarget = oldW;
1465 foundW = oldW;
1466 foundI = oldI;
1467 } else {
1468 // The new target is below the old one.
1469 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001470 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001471 }
1472 mUpperWallpaperTarget = oldW;
1473 mLowerWallpaperTarget = foundW;
1474 }
1475 }
1476 }
1477 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001478
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001479 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001480 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001481 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1482 || (mLowerWallpaperTarget.mAppToken != null
1483 && mLowerWallpaperTarget.mAppToken.animation != null);
1484 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1485 || (mUpperWallpaperTarget.mAppToken != null
1486 && mUpperWallpaperTarget.mAppToken.animation != null);
1487 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001488 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001489 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001490 }
1491 mLowerWallpaperTarget = null;
1492 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001493 }
1494 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001495
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001496 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001497 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001498 // The window is visible to the compositor... but is it visible
1499 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001500 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001501 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001502
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001503 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001504 // its layer adjustment. Only do this if we are not transfering
1505 // between two wallpaper targets.
1506 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001507 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001508 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001509
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001510 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1511 * TYPE_LAYER_MULTIPLIER
1512 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001513
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001514 // Now w is the window we are supposed to be behind... but we
1515 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001516 // AND any starting window associated with it, AND below the
1517 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001518 while (foundI > 0) {
1519 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001520 if (wb.mBaseLayer < maxLayer &&
1521 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001522 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001523 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001524 // This window is not related to the previous one in any
1525 // interesting way, so stop here.
1526 break;
1527 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001528 foundW = wb;
1529 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001530 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001531 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001532 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001533 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001534
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001535 if (foundW == null && topCurW != null) {
1536 // There is no wallpaper target, so it goes at the bottom.
1537 // We will assume it is the same place as last time, if known.
1538 foundW = topCurW;
1539 foundI = topCurI+1;
1540 } else {
1541 // Okay i is the position immediately above the wallpaper. Look at
1542 // what is below it for later.
1543 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1544 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001545
Dianne Hackborn284ac932009-08-28 10:34:25 -07001546 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001547 if (mWallpaperTarget.mWallpaperX >= 0) {
1548 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001549 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001550 }
1551 if (mWallpaperTarget.mWallpaperY >= 0) {
1552 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001553 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001554 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001555 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001556
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001557 // Start stepping backwards from here, ensuring that our wallpaper windows
1558 // are correctly placed.
1559 int curTokenIndex = mWallpaperTokens.size();
1560 while (curTokenIndex > 0) {
1561 curTokenIndex--;
1562 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001563 if (token.hidden == visible) {
1564 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1565 token.hidden = !visible;
1566 // Need to do a layout to ensure the wallpaper now has the
1567 // correct size.
1568 mLayoutNeeded = true;
1569 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001571 int curWallpaperIndex = token.windows.size();
1572 while (curWallpaperIndex > 0) {
1573 curWallpaperIndex--;
1574 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001575
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001576 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001577 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001578 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001579
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001580 // First, make sure the client has the current visibility
1581 // state.
1582 if (wallpaper.mWallpaperVisible != visible) {
1583 wallpaper.mWallpaperVisible = visible;
1584 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001586 "Setting visibility of wallpaper " + wallpaper
1587 + ": " + visible);
1588 wallpaper.mClient.dispatchAppVisibility(visible);
1589 } catch (RemoteException e) {
1590 }
1591 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001592
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001593 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001594 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001595 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001596
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001597 // First, if this window is at the current index, then all
1598 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001599 if (wallpaper == foundW) {
1600 foundI--;
1601 foundW = foundI > 0
1602 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001603 continue;
1604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001605
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001606 // The window didn't match... the current wallpaper window,
1607 // wherever it is, is in the wrong place, so make sure it is
1608 // not in the list.
1609 int oldIndex = localmWindows.indexOf(wallpaper);
1610 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001611 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001612 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001613 localmWindows.remove(oldIndex);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001614 if (oldIndex < foundI) {
1615 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001616 }
1617 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001618
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001619 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001620 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001621 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001622 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001623
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001624 localmWindows.add(foundI, wallpaper);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001625 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001626 }
1627 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001628
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001629 return changed;
1630 }
1631
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001632 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001633 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001634 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001635 mWallpaperAnimLayerAdjustment = adj;
1636 int curTokenIndex = mWallpaperTokens.size();
1637 while (curTokenIndex > 0) {
1638 curTokenIndex--;
1639 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1640 int curWallpaperIndex = token.windows.size();
1641 while (curWallpaperIndex > 0) {
1642 curWallpaperIndex--;
1643 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1644 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001645 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001646 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001647 }
1648 }
1649 }
1650
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001651 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1652 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001653 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001654 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001655 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001656 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001657 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1658 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1659 changed = wallpaperWin.mXOffset != offset;
1660 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001661 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001662 + wallpaperWin + " x: " + offset);
1663 wallpaperWin.mXOffset = offset;
1664 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001665 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001666 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001667 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001668 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001670
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001671 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001672 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001673 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1674 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1675 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001677 + wallpaperWin + " y: " + offset);
1678 changed = true;
1679 wallpaperWin.mYOffset = offset;
1680 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001681 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001682 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001683 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001684 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001685 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001686
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001687 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001688 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001689 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001690 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1691 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001692 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001693 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001694 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001695 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001696 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1697 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001698 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001699 if (mWaitingOnWallpaper != null) {
1700 long start = SystemClock.uptimeMillis();
1701 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1702 < start) {
1703 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001704 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001705 "Waiting for offset complete...");
1706 mWindowMap.wait(WALLPAPER_TIMEOUT);
1707 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001708 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001709 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001710 if ((start+WALLPAPER_TIMEOUT)
1711 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001712 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001713 + wallpaperWin);
1714 mLastWallpaperTimeoutTime = start;
1715 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001716 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001717 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001718 }
1719 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001720 } catch (RemoteException e) {
1721 }
1722 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001723
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001724 return changed;
1725 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001726
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001727 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001728 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001729 if (mWaitingOnWallpaper != null &&
1730 mWaitingOnWallpaper.mClient.asBinder() == window) {
1731 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001732 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001733 }
1734 }
1735 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001736
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001737 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001738 final int dw = mDisplay.getWidth();
1739 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001740
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001741 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001742
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001743 WindowState target = mWallpaperTarget;
1744 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001745 if (target.mWallpaperX >= 0) {
1746 mLastWallpaperX = target.mWallpaperX;
1747 } else if (changingTarget.mWallpaperX >= 0) {
1748 mLastWallpaperX = changingTarget.mWallpaperX;
1749 }
1750 if (target.mWallpaperY >= 0) {
1751 mLastWallpaperY = target.mWallpaperY;
1752 } else if (changingTarget.mWallpaperY >= 0) {
1753 mLastWallpaperY = changingTarget.mWallpaperY;
1754 }
1755 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001756
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001757 int curTokenIndex = mWallpaperTokens.size();
1758 while (curTokenIndex > 0) {
1759 curTokenIndex--;
1760 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1761 int curWallpaperIndex = token.windows.size();
1762 while (curWallpaperIndex > 0) {
1763 curWallpaperIndex--;
1764 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1765 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1766 wallpaper.computeShownFrameLocked();
1767 changed = true;
1768 // We only want to be synchronous with one wallpaper.
1769 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001770 }
1771 }
1772 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001773
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001774 return changed;
1775 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001776
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001777 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001778 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001779 final int dw = mDisplay.getWidth();
1780 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001781
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001782 int curTokenIndex = mWallpaperTokens.size();
1783 while (curTokenIndex > 0) {
1784 curTokenIndex--;
1785 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001786 if (token.hidden == visible) {
1787 token.hidden = !visible;
1788 // Need to do a layout to ensure the wallpaper now has the
1789 // correct size.
1790 mLayoutNeeded = true;
1791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001792
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001793 int curWallpaperIndex = token.windows.size();
1794 while (curWallpaperIndex > 0) {
1795 curWallpaperIndex--;
1796 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1797 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001798 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001799 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001800
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001801 if (wallpaper.mWallpaperVisible != visible) {
1802 wallpaper.mWallpaperVisible = visible;
1803 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001804 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001805 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001806 + ": " + visible);
1807 wallpaper.mClient.dispatchAppVisibility(visible);
1808 } catch (RemoteException e) {
1809 }
1810 }
1811 }
1812 }
1813 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001814
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001815 void sendPointerToWallpaperLocked(WindowState srcWin,
1816 MotionEvent pointer, long eventTime) {
1817 int curTokenIndex = mWallpaperTokens.size();
1818 while (curTokenIndex > 0) {
1819 curTokenIndex--;
1820 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1821 int curWallpaperIndex = token.windows.size();
1822 while (curWallpaperIndex > 0) {
1823 curWallpaperIndex--;
1824 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1825 if ((wallpaper.mAttrs.flags &
1826 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
1827 continue;
1828 }
1829 try {
1830 MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
Dianne Hackborn6adba242009-11-10 11:10:09 -08001831 if (srcWin != null) {
1832 ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
1833 srcWin.mFrame.top-wallpaper.mFrame.top);
1834 } else {
1835 ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
1836 }
1837 switch (pointer.getAction()) {
1838 case MotionEvent.ACTION_DOWN:
1839 mSendingPointersToWallpaper = true;
1840 break;
1841 case MotionEvent.ACTION_UP:
1842 mSendingPointersToWallpaper = false;
1843 break;
1844 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001845 wallpaper.mClient.dispatchPointer(ev, eventTime, false);
1846 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001847 Slog.w(TAG, "Failure sending pointer to wallpaper", e);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001848 }
1849 }
1850 }
1851 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001852
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001853 void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
1854 MotionEvent pointer, long eventTime, boolean skipped) {
1855 if (relWin != null) {
1856 mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
1857 } else {
1858 mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
1859 }
1860
1861 // If we sent an initial down to the wallpaper, then continue
1862 // sending events until the final up.
1863 if (mSendingPointersToWallpaper) {
1864 if (skipped) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001865 Slog.i(TAG, "Sending skipped pointer to wallpaper!");
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001866 }
1867 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1868
1869 // If we are on top of the wallpaper, then the wallpaper also
1870 // gets to see this movement.
1871 } else if (srcWin != null
1872 && pointer.getAction() == MotionEvent.ACTION_DOWN
1873 && mWallpaperTarget == srcWin
1874 && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
1875 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1876 }
1877 }
1878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001879 public int addWindow(Session session, IWindow client,
1880 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001881 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 int res = mPolicy.checkAddPermission(attrs);
1883 if (res != WindowManagerImpl.ADD_OKAY) {
1884 return res;
1885 }
Romain Guy06882f82009-06-10 13:36:04 -07001886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 boolean reportNewConfig = false;
1888 WindowState attachedWindow = null;
1889 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 synchronized(mWindowMap) {
1892 // Instantiating a Display requires talking with the simulator,
1893 // so don't do it until we know the system is mostly up and
1894 // running.
1895 if (mDisplay == null) {
1896 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1897 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001898 mInitialDisplayWidth = mDisplay.getWidth();
1899 mInitialDisplayHeight = mDisplay.getHeight();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001900 if (ENABLE_NATIVE_INPUT_DISPATCH) {
1901 mInputManager.setDisplaySize(0,
1902 mInitialDisplayWidth, mInitialDisplayHeight);
1903 } else {
1904 mQueue.setDisplay(mDisplay);
1905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 reportNewConfig = true;
1907 }
Romain Guy06882f82009-06-10 13:36:04 -07001908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001910 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1912 }
1913
1914 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001915 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001917 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 + attrs.token + ". Aborting.");
1919 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1920 }
1921 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1922 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001923 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001924 + attrs.token + ". Aborting.");
1925 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1926 }
1927 }
1928
1929 boolean addToken = false;
1930 WindowToken token = mTokenMap.get(attrs.token);
1931 if (token == null) {
1932 if (attrs.type >= FIRST_APPLICATION_WINDOW
1933 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001934 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 + attrs.token + ". Aborting.");
1936 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1937 }
1938 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001939 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 + attrs.token + ". Aborting.");
1941 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1942 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001943 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001944 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001945 + attrs.token + ". Aborting.");
1946 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 token = new WindowToken(attrs.token, -1, false);
1949 addToken = true;
1950 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1951 && attrs.type <= LAST_APPLICATION_WINDOW) {
1952 AppWindowToken atoken = token.appWindowToken;
1953 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001954 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 + token + ". Aborting.");
1956 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1957 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001958 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 + token + ". Aborting.");
1960 return WindowManagerImpl.ADD_APP_EXITING;
1961 }
1962 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1963 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001964 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1966 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1967 }
1968 } else if (attrs.type == TYPE_INPUT_METHOD) {
1969 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001970 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 + attrs.token + ". Aborting.");
1972 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1973 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001974 } else if (attrs.type == TYPE_WALLPAPER) {
1975 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001976 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001977 + attrs.token + ". Aborting.");
1978 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 }
1981
1982 win = new WindowState(session, client, token,
1983 attachedWindow, attrs, viewVisibility);
1984 if (win.mDeathRecipient == null) {
1985 // Client has apparently died, so there is no reason to
1986 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001987 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 + " that is dead, aborting.");
1989 return WindowManagerImpl.ADD_APP_EXITING;
1990 }
1991
1992 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001994 res = mPolicy.prepareAddWindowLw(win, attrs);
1995 if (res != WindowManagerImpl.ADD_OKAY) {
1996 return res;
1997 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001998
1999 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2000 if (outInputChannel != null) {
2001 String name = win.makeInputChannelName();
2002 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2003 win.mInputChannel = inputChannels[0];
2004 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2005
2006 mInputManager.registerInputChannel(win.mInputChannel);
2007 }
2008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002009
2010 // From now on, no exceptions or errors allowed!
2011
2012 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002014 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002016 if (addToken) {
2017 mTokenMap.put(attrs.token, token);
2018 mTokenList.add(token);
2019 }
2020 win.attach();
2021 mWindowMap.put(client.asBinder(), win);
2022
2023 if (attrs.type == TYPE_APPLICATION_STARTING &&
2024 token.appWindowToken != null) {
2025 token.appWindowToken.startingWindow = win;
2026 }
2027
2028 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002030 if (attrs.type == TYPE_INPUT_METHOD) {
2031 mInputMethodWindow = win;
2032 addInputMethodWindowToListLocked(win);
2033 imMayMove = false;
2034 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2035 mInputMethodDialogs.add(win);
2036 addWindowToListInOrderLocked(win, true);
2037 adjustInputMethodDialogsLocked();
2038 imMayMove = false;
2039 } else {
2040 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002041 if (attrs.type == TYPE_WALLPAPER) {
2042 mLastWallpaperTimeoutTime = 0;
2043 adjustWallpaperWindowsLocked();
2044 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002045 adjustWallpaperWindowsLocked();
2046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 }
Romain Guy06882f82009-06-10 13:36:04 -07002048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002049 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002053 if (mInTouchMode) {
2054 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2055 }
2056 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2057 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2058 }
Romain Guy06882f82009-06-10 13:36:04 -07002059
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002060 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002061 if (win.canReceiveKeys()) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002062 if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
2063 == true) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002064 imMayMove = false;
2065 }
2066 }
Romain Guy06882f82009-06-10 13:36:04 -07002067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002069 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002070 }
Romain Guy06882f82009-06-10 13:36:04 -07002071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 assignLayersLocked();
2073 // Don't do layout here, the window must call
2074 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 //dump();
2077
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002078 if (focusChanged) {
2079 if (mCurrentFocus != null) {
2080 mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
2081 }
2082 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002083 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002084 TAG, "New client " + client.asBinder()
2085 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002086
2087 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2088 reportNewConfig = true;
2089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 }
2091
2092 // sendNewConfiguration() checks caller permissions so we must call it with
2093 // privilege. updateOrientationFromAppTokens() clears and resets the caller
2094 // identity anyway, so it's safe to just clear & restore around this whole
2095 // block.
2096 final long origId = Binder.clearCallingIdentity();
2097 if (reportNewConfig) {
2098 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 }
2100 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 return res;
2103 }
Romain Guy06882f82009-06-10 13:36:04 -07002104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 public void removeWindow(Session session, IWindow client) {
2106 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002107 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 if (win == null) {
2109 return;
2110 }
2111 removeWindowLocked(session, win);
2112 }
2113 }
Romain Guy06882f82009-06-10 13:36:04 -07002114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002115 public void removeWindowLocked(Session session, WindowState win) {
2116
Joe Onorato8a9b2202010-02-26 18:56:32 -08002117 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 TAG, "Remove " + win + " client="
2119 + Integer.toHexString(System.identityHashCode(
2120 win.mClient.asBinder()))
2121 + ", surface=" + win.mSurface);
2122
2123 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002124
Joe Onorato8a9b2202010-02-26 18:56:32 -08002125 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2127 + " mExiting=" + win.mExiting
2128 + " isAnimating=" + win.isAnimating()
2129 + " app-animation="
2130 + (win.mAppToken != null ? win.mAppToken.animation : null)
2131 + " inPendingTransaction="
2132 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2133 + " mDisplayFrozen=" + mDisplayFrozen);
2134 // Visibility of the removed window. Will be used later to update orientation later on.
2135 boolean wasVisible = false;
2136 // First, see if we need to run an animation. If we do, we have
2137 // to hold off on removing the window until the animation is done.
2138 // If the display is frozen, just remove immediately, since the
2139 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002140 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 // If we are not currently running the exit animation, we
2142 // need to see about starting one.
2143 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2146 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2147 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2148 }
2149 // Try starting an animation.
2150 if (applyAnimationLocked(win, transit, false)) {
2151 win.mExiting = true;
2152 }
2153 }
2154 if (win.mExiting || win.isAnimating()) {
2155 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002156 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 win.mExiting = true;
2158 win.mRemoveOnExit = true;
2159 mLayoutNeeded = true;
2160 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2161 performLayoutAndPlaceSurfacesLocked();
2162 if (win.mAppToken != null) {
2163 win.mAppToken.updateReportedVisibilityLocked();
2164 }
2165 //dump();
2166 Binder.restoreCallingIdentity(origId);
2167 return;
2168 }
2169 }
2170
2171 removeWindowInnerLocked(session, win);
2172 // Removing a visible window will effect the computed orientation
2173 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002174 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002175 != mForcedAppOrientation
2176 && updateOrientationFromAppTokensLocked()) {
2177 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 }
2179 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2180 Binder.restoreCallingIdentity(origId);
2181 }
Romain Guy06882f82009-06-10 13:36:04 -07002182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07002184 mKeyWaiter.finishedKey(session, win.mClient, true,
2185 KeyWaiter.RETURN_NOTHING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 mKeyWaiter.releasePendingPointerLocked(win.mSession);
2187 mKeyWaiter.releasePendingTrackballLocked(win.mSession);
Romain Guy06882f82009-06-10 13:36:04 -07002188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191 if (mInputMethodTarget == win) {
2192 moveInputMethodWindowsIfNeededLocked(false);
2193 }
Romain Guy06882f82009-06-10 13:36:04 -07002194
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002195 if (false) {
2196 RuntimeException e = new RuntimeException("here");
2197 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002198 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002199 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 mPolicy.removeWindowLw(win);
2202 win.removeLocked();
2203
2204 mWindowMap.remove(win.mClient.asBinder());
2205 mWindows.remove(win);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002206 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207
2208 if (mInputMethodWindow == win) {
2209 mInputMethodWindow = null;
2210 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2211 mInputMethodDialogs.remove(win);
2212 }
Romain Guy06882f82009-06-10 13:36:04 -07002213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 final WindowToken token = win.mToken;
2215 final AppWindowToken atoken = win.mAppToken;
2216 token.windows.remove(win);
2217 if (atoken != null) {
2218 atoken.allAppWindows.remove(win);
2219 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002220 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 TAG, "**** Removing window " + win + ": count="
2222 + token.windows.size());
2223 if (token.windows.size() == 0) {
2224 if (!token.explicit) {
2225 mTokenMap.remove(token.token);
2226 mTokenList.remove(token);
2227 } else if (atoken != null) {
2228 atoken.firstWindowDrawn = false;
2229 }
2230 }
2231
2232 if (atoken != null) {
2233 if (atoken.startingWindow == win) {
2234 atoken.startingWindow = null;
2235 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2236 // If this is the last window and we had requested a starting
2237 // transition window, well there is no point now.
2238 atoken.startingData = null;
2239 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2240 // If this is the last window except for a starting transition
2241 // window, we need to get rid of the starting transition.
2242 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002243 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 + ": no more real windows");
2245 }
2246 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2247 mH.sendMessage(m);
2248 }
2249 }
Romain Guy06882f82009-06-10 13:36:04 -07002250
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002251 if (win.mAttrs.type == TYPE_WALLPAPER) {
2252 mLastWallpaperTimeoutTime = 0;
2253 adjustWallpaperWindowsLocked();
2254 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002255 adjustWallpaperWindowsLocked();
2256 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 if (!mInLayout) {
2259 assignLayersLocked();
2260 mLayoutNeeded = true;
2261 performLayoutAndPlaceSurfacesLocked();
2262 if (win.mAppToken != null) {
2263 win.mAppToken.updateReportedVisibilityLocked();
2264 }
2265 }
2266 }
2267
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002268 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2269 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2270 + ": " + msg + " / " + w.mAttrs.getTitle();
2271 if (where != null) {
2272 Slog.i(TAG, str, where);
2273 } else {
2274 Slog.i(TAG, str);
2275 }
2276 }
2277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2279 long origId = Binder.clearCallingIdentity();
2280 try {
2281 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002282 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002284 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 Surface.openTransaction();
2286 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002287 if (SHOW_TRANSACTIONS) logSurface(w,
2288 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 w.mSurface.setTransparentRegionHint(region);
2290 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002291 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 Surface.closeTransaction();
2293 }
2294 }
2295 }
2296 } finally {
2297 Binder.restoreCallingIdentity(origId);
2298 }
2299 }
2300
2301 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002302 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 Rect visibleInsets) {
2304 long origId = Binder.clearCallingIdentity();
2305 try {
2306 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002307 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308 if (w != null) {
2309 w.mGivenInsetsPending = false;
2310 w.mGivenContentInsets.set(contentInsets);
2311 w.mGivenVisibleInsets.set(visibleInsets);
2312 w.mTouchableInsets = touchableInsets;
2313 mLayoutNeeded = true;
2314 performLayoutAndPlaceSurfacesLocked();
2315 }
2316 }
2317 } finally {
2318 Binder.restoreCallingIdentity(origId);
2319 }
2320 }
Romain Guy06882f82009-06-10 13:36:04 -07002321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 public void getWindowDisplayFrame(Session session, IWindow client,
2323 Rect outDisplayFrame) {
2324 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002325 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 if (win == null) {
2327 outDisplayFrame.setEmpty();
2328 return;
2329 }
2330 outDisplayFrame.set(win.mDisplayFrame);
2331 }
2332 }
2333
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002334 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2335 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002336 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2337 window.mWallpaperX = x;
2338 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002339 window.mWallpaperXStep = xStep;
2340 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002341 if (updateWallpaperOffsetLocked(window, true)) {
2342 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002343 }
2344 }
2345 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002346
Dianne Hackborn75804932009-10-20 20:15:20 -07002347 void wallpaperCommandComplete(IBinder window, Bundle result) {
2348 synchronized (mWindowMap) {
2349 if (mWaitingOnWallpaper != null &&
2350 mWaitingOnWallpaper.mClient.asBinder() == window) {
2351 mWaitingOnWallpaper = null;
2352 mWindowMap.notifyAll();
2353 }
2354 }
2355 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002356
Dianne Hackborn75804932009-10-20 20:15:20 -07002357 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2358 String action, int x, int y, int z, Bundle extras, boolean sync) {
2359 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2360 || window == mUpperWallpaperTarget) {
2361 boolean doWait = sync;
2362 int curTokenIndex = mWallpaperTokens.size();
2363 while (curTokenIndex > 0) {
2364 curTokenIndex--;
2365 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2366 int curWallpaperIndex = token.windows.size();
2367 while (curWallpaperIndex > 0) {
2368 curWallpaperIndex--;
2369 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2370 try {
2371 wallpaper.mClient.dispatchWallpaperCommand(action,
2372 x, y, z, extras, sync);
2373 // We only want to be synchronous with one wallpaper.
2374 sync = false;
2375 } catch (RemoteException e) {
2376 }
2377 }
2378 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002379
Dianne Hackborn75804932009-10-20 20:15:20 -07002380 if (doWait) {
2381 // XXX Need to wait for result.
2382 }
2383 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002384
Dianne Hackborn75804932009-10-20 20:15:20 -07002385 return null;
2386 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002388 public int relayoutWindow(Session session, IWindow client,
2389 WindowManager.LayoutParams attrs, int requestedWidth,
2390 int requestedHeight, int viewVisibility, boolean insetsPending,
2391 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002392 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 boolean displayed = false;
2394 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002395 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002399 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 if (win == null) {
2401 return 0;
2402 }
2403 win.mRequestedWidth = requestedWidth;
2404 win.mRequestedHeight = requestedHeight;
2405
2406 if (attrs != null) {
2407 mPolicy.adjustWindowParamsLw(attrs);
2408 }
Romain Guy06882f82009-06-10 13:36:04 -07002409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002410 int attrChanges = 0;
2411 int flagChanges = 0;
2412 if (attrs != null) {
2413 flagChanges = win.mAttrs.flags ^= attrs.flags;
2414 attrChanges = win.mAttrs.copyFrom(attrs);
2415 }
2416
Joe Onorato8a9b2202010-02-26 18:56:32 -08002417 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418
2419 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2420 win.mAlpha = attrs.alpha;
2421 }
2422
2423 final boolean scaledWindow =
2424 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2425
2426 if (scaledWindow) {
2427 // requested{Width|Height} Surface's physical size
2428 // attrs.{width|height} Size on screen
2429 win.mHScale = (attrs.width != requestedWidth) ?
2430 (attrs.width / (float)requestedWidth) : 1.0f;
2431 win.mVScale = (attrs.height != requestedHeight) ?
2432 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002433 } else {
2434 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 }
2436
2437 boolean imMayMove = (flagChanges&(
2438 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2439 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 boolean focusMayChange = win.mViewVisibility != viewVisibility
2442 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2443 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002444
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002445 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2446 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 win.mRelayoutCalled = true;
2449 final int oldVisibility = win.mViewVisibility;
2450 win.mViewVisibility = viewVisibility;
2451 if (viewVisibility == View.VISIBLE &&
2452 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2453 displayed = !win.isVisibleLw();
2454 if (win.mExiting) {
2455 win.mExiting = false;
2456 win.mAnimation = null;
2457 }
2458 if (win.mDestroying) {
2459 win.mDestroying = false;
2460 mDestroySurface.remove(win);
2461 }
2462 if (oldVisibility == View.GONE) {
2463 win.mEnterAnimationPending = true;
2464 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002465 if (displayed) {
2466 if (win.mSurface != null && !win.mDrawPending
2467 && !win.mCommitDrawPending && !mDisplayFrozen
2468 && mPolicy.isScreenOn()) {
2469 applyEnterAnimationLocked(win);
2470 }
2471 if ((win.mAttrs.flags
2472 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2473 if (DEBUG_VISIBILITY) Slog.v(TAG,
2474 "Relayout window turning screen on: " + win);
2475 win.mTurnOnScreen = true;
2476 }
2477 int diff = 0;
2478 if (win.mConfiguration != mCurConfiguration
2479 && (win.mConfiguration == null
2480 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2481 win.mConfiguration = mCurConfiguration;
2482 if (DEBUG_CONFIGURATION) {
2483 Slog.i(TAG, "Window " + win + " visible with new config: "
2484 + win.mConfiguration + " / 0x"
2485 + Integer.toHexString(diff));
2486 }
2487 outConfig.setTo(mCurConfiguration);
2488 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2491 // To change the format, we need to re-build the surface.
2492 win.destroySurfaceLocked();
2493 displayed = true;
2494 }
2495 try {
2496 Surface surface = win.createSurfaceLocked();
2497 if (surface != null) {
2498 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002499 win.mReportDestroySurface = false;
2500 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002501 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002502 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002504 // For some reason there isn't a surface. Clear the
2505 // caller's object so they see the same state.
2506 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 }
2508 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002509 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002510 + client + " (" + win.mAttrs.getTitle() + ")",
2511 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002512 Binder.restoreCallingIdentity(origId);
2513 return 0;
2514 }
2515 if (displayed) {
2516 focusMayChange = true;
2517 }
2518 if (win.mAttrs.type == TYPE_INPUT_METHOD
2519 && mInputMethodWindow == null) {
2520 mInputMethodWindow = win;
2521 imMayMove = true;
2522 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002523 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2524 && win.mAppToken != null
2525 && win.mAppToken.startingWindow != null) {
2526 // Special handling of starting window over the base
2527 // window of the app: propagate lock screen flags to it,
2528 // to provide the correct semantics while starting.
2529 final int mask =
2530 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002531 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2532 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002533 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2534 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 } else {
2537 win.mEnterAnimationPending = false;
2538 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002539 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002540 + ": mExiting=" + win.mExiting
2541 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 // If we are not currently running the exit animation, we
2543 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002544 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 // Try starting an animation; if there isn't one, we
2546 // can destroy the surface right away.
2547 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2548 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2549 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2550 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002551 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002553 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 win.mExiting = true;
2555 mKeyWaiter.finishedKey(session, client, true,
2556 KeyWaiter.RETURN_NOTHING);
2557 } else if (win.isAnimating()) {
2558 // Currently in a hide animation... turn this into
2559 // an exit.
2560 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002561 } else if (win == mWallpaperTarget) {
2562 // If the wallpaper is currently behind this
2563 // window, we need to change both of them inside
2564 // of a transaction to avoid artifacts.
2565 win.mExiting = true;
2566 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 } else {
2568 if (mInputMethodWindow == win) {
2569 mInputMethodWindow = null;
2570 }
2571 win.destroySurfaceLocked();
2572 }
2573 }
2574 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002575
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002576 if (win.mSurface == null || (win.getAttrs().flags
2577 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2578 || win.mSurfacePendingDestroy) {
2579 // We are being called from a local process, which
2580 // means outSurface holds its current surface. Ensure the
2581 // surface object is cleared, but we don't want it actually
2582 // destroyed at this point.
2583 win.mSurfacePendingDestroy = false;
2584 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002585 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002586 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002587 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002588 "Keeping surface, will report destroy: " + win);
2589 win.mReportDestroySurface = true;
2590 outSurface.copyFrom(win.mSurface);
2591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 }
2593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 if (focusMayChange) {
2595 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2596 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597 imMayMove = false;
2598 }
2599 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2600 }
Romain Guy06882f82009-06-10 13:36:04 -07002601
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002602 // updateFocusedWindowLocked() already assigned layers so we only need to
2603 // reassign them at this point if the IM window state gets shuffled
2604 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002607 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2608 // Little hack here -- we -should- be able to rely on the
2609 // function to return true if the IME has moved and needs
2610 // its layer recomputed. However, if the IME was hidden
2611 // and isn't actually moved in the list, its layer may be
2612 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 assignLayers = true;
2614 }
2615 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002616 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002617 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002618 assignLayers = true;
2619 }
2620 }
Romain Guy06882f82009-06-10 13:36:04 -07002621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 mLayoutNeeded = true;
2623 win.mGivenInsetsPending = insetsPending;
2624 if (assignLayers) {
2625 assignLayersLocked();
2626 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002627 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002629 if (displayed && win.mIsWallpaper) {
2630 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002631 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 if (win.mAppToken != null) {
2634 win.mAppToken.updateReportedVisibilityLocked();
2635 }
2636 outFrame.set(win.mFrame);
2637 outContentInsets.set(win.mContentInsets);
2638 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002639 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002640 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002641 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002642 + ", requestedHeight=" + requestedHeight
2643 + ", viewVisibility=" + viewVisibility
2644 + "\nRelayout returning frame=" + outFrame
2645 + ", surface=" + outSurface);
2646
Joe Onorato8a9b2202010-02-26 18:56:32 -08002647 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2649
2650 inTouchMode = mInTouchMode;
2651 }
2652
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002653 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 sendNewConfiguration();
2655 }
Romain Guy06882f82009-06-10 13:36:04 -07002656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2660 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2661 }
2662
2663 public void finishDrawingWindow(Session session, IWindow client) {
2664 final long origId = Binder.clearCallingIdentity();
2665 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002666 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002668 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2669 adjustWallpaperWindowsLocked();
2670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 mLayoutNeeded = true;
2672 performLayoutAndPlaceSurfacesLocked();
2673 }
2674 }
2675 Binder.restoreCallingIdentity(origId);
2676 }
2677
2678 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002679 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 + (lp != null ? lp.packageName : null)
2681 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2682 if (lp != null && lp.windowAnimations != 0) {
2683 // If this is a system resource, don't try to load it from the
2684 // application resources. It is nice to avoid loading application
2685 // resources if we can.
2686 String packageName = lp.packageName != null ? lp.packageName : "android";
2687 int resId = lp.windowAnimations;
2688 if ((resId&0xFF000000) == 0x01000000) {
2689 packageName = "android";
2690 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002691 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 + packageName);
2693 return AttributeCache.instance().get(packageName, resId,
2694 com.android.internal.R.styleable.WindowAnimation);
2695 }
2696 return null;
2697 }
Romain Guy06882f82009-06-10 13:36:04 -07002698
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002699 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002700 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002701 + packageName + " resId=0x" + Integer.toHexString(resId));
2702 if (packageName != null) {
2703 if ((resId&0xFF000000) == 0x01000000) {
2704 packageName = "android";
2705 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002706 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002707 + packageName);
2708 return AttributeCache.instance().get(packageName, resId,
2709 com.android.internal.R.styleable.WindowAnimation);
2710 }
2711 return null;
2712 }
2713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 private void applyEnterAnimationLocked(WindowState win) {
2715 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2716 if (win.mEnterAnimationPending) {
2717 win.mEnterAnimationPending = false;
2718 transit = WindowManagerPolicy.TRANSIT_ENTER;
2719 }
2720
2721 applyAnimationLocked(win, transit, true);
2722 }
2723
2724 private boolean applyAnimationLocked(WindowState win,
2725 int transit, boolean isEntrance) {
2726 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2727 // If we are trying to apply an animation, but already running
2728 // an animation of the same type, then just leave that one alone.
2729 return true;
2730 }
Romain Guy06882f82009-06-10 13:36:04 -07002731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 // Only apply an animation if the display isn't frozen. If it is
2733 // frozen, there is no reason to animate and it can cause strange
2734 // artifacts when we unfreeze the display if some different animation
2735 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002736 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 int anim = mPolicy.selectAnimationLw(win, transit);
2738 int attr = -1;
2739 Animation a = null;
2740 if (anim != 0) {
2741 a = AnimationUtils.loadAnimation(mContext, anim);
2742 } else {
2743 switch (transit) {
2744 case WindowManagerPolicy.TRANSIT_ENTER:
2745 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2746 break;
2747 case WindowManagerPolicy.TRANSIT_EXIT:
2748 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2749 break;
2750 case WindowManagerPolicy.TRANSIT_SHOW:
2751 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2752 break;
2753 case WindowManagerPolicy.TRANSIT_HIDE:
2754 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2755 break;
2756 }
2757 if (attr >= 0) {
2758 a = loadAnimation(win.mAttrs, attr);
2759 }
2760 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002761 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2763 + " mAnimation=" + win.mAnimation
2764 + " isEntrance=" + isEntrance);
2765 if (a != null) {
2766 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002767 RuntimeException e = null;
2768 if (!HIDE_STACK_CRAWLS) {
2769 e = new RuntimeException();
2770 e.fillInStackTrace();
2771 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002772 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002773 }
2774 win.setAnimation(a);
2775 win.mAnimationIsEntrance = isEntrance;
2776 }
2777 } else {
2778 win.clearAnimation();
2779 }
2780
2781 return win.mAnimation != null;
2782 }
2783
2784 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2785 int anim = 0;
2786 Context context = mContext;
2787 if (animAttr >= 0) {
2788 AttributeCache.Entry ent = getCachedAnimations(lp);
2789 if (ent != null) {
2790 context = ent.context;
2791 anim = ent.array.getResourceId(animAttr, 0);
2792 }
2793 }
2794 if (anim != 0) {
2795 return AnimationUtils.loadAnimation(context, anim);
2796 }
2797 return null;
2798 }
Romain Guy06882f82009-06-10 13:36:04 -07002799
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002800 private Animation loadAnimation(String packageName, int resId) {
2801 int anim = 0;
2802 Context context = mContext;
2803 if (resId >= 0) {
2804 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2805 if (ent != null) {
2806 context = ent.context;
2807 anim = resId;
2808 }
2809 }
2810 if (anim != 0) {
2811 return AnimationUtils.loadAnimation(context, anim);
2812 }
2813 return null;
2814 }
2815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 private boolean applyAnimationLocked(AppWindowToken wtoken,
2817 WindowManager.LayoutParams lp, int transit, boolean enter) {
2818 // Only apply an animation if the display isn't frozen. If it is
2819 // frozen, there is no reason to animate and it can cause strange
2820 // artifacts when we unfreeze the display if some different animation
2821 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002822 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002823 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002824 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002825 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002826 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002827 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002828 } else if (mNextAppTransitionPackage != null) {
2829 a = loadAnimation(mNextAppTransitionPackage, enter ?
2830 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002831 } else {
2832 int animAttr = 0;
2833 switch (transit) {
2834 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2835 animAttr = enter
2836 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2837 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2838 break;
2839 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2840 animAttr = enter
2841 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2842 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2843 break;
2844 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2845 animAttr = enter
2846 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2847 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2848 break;
2849 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2850 animAttr = enter
2851 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2852 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2853 break;
2854 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2855 animAttr = enter
2856 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2857 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2858 break;
2859 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2860 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002861 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002862 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2863 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002864 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002865 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002866 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2867 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002868 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002869 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002870 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002871 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2872 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2873 break;
2874 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2875 animAttr = enter
2876 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2877 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2878 break;
2879 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2880 animAttr = enter
2881 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2882 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002883 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002884 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002885 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002886 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002887 + " anim=" + a
2888 + " animAttr=0x" + Integer.toHexString(animAttr)
2889 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 if (a != null) {
2892 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002893 RuntimeException e = null;
2894 if (!HIDE_STACK_CRAWLS) {
2895 e = new RuntimeException();
2896 e.fillInStackTrace();
2897 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002898 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 }
2900 wtoken.setAnimation(a);
2901 }
2902 } else {
2903 wtoken.clearAnimation();
2904 }
2905
2906 return wtoken.animation != null;
2907 }
2908
2909 // -------------------------------------------------------------
2910 // Application Window Tokens
2911 // -------------------------------------------------------------
2912
2913 public void validateAppTokens(List tokens) {
2914 int v = tokens.size()-1;
2915 int m = mAppTokens.size()-1;
2916 while (v >= 0 && m >= 0) {
2917 AppWindowToken wtoken = mAppTokens.get(m);
2918 if (wtoken.removed) {
2919 m--;
2920 continue;
2921 }
2922 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002923 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2925 }
2926 v--;
2927 m--;
2928 }
2929 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002930 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002931 v--;
2932 }
2933 while (m >= 0) {
2934 AppWindowToken wtoken = mAppTokens.get(m);
2935 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002936 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 }
2938 m--;
2939 }
2940 }
2941
2942 boolean checkCallingPermission(String permission, String func) {
2943 // Quick check: if the calling permission is me, it's all okay.
2944 if (Binder.getCallingPid() == Process.myPid()) {
2945 return true;
2946 }
Romain Guy06882f82009-06-10 13:36:04 -07002947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 if (mContext.checkCallingPermission(permission)
2949 == PackageManager.PERMISSION_GRANTED) {
2950 return true;
2951 }
2952 String msg = "Permission Denial: " + func + " from pid="
2953 + Binder.getCallingPid()
2954 + ", uid=" + Binder.getCallingUid()
2955 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002956 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 return false;
2958 }
Romain Guy06882f82009-06-10 13:36:04 -07002959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 AppWindowToken findAppWindowToken(IBinder token) {
2961 WindowToken wtoken = mTokenMap.get(token);
2962 if (wtoken == null) {
2963 return null;
2964 }
2965 return wtoken.appWindowToken;
2966 }
Romain Guy06882f82009-06-10 13:36:04 -07002967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002968 public void addWindowToken(IBinder token, int type) {
2969 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2970 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002971 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 }
Romain Guy06882f82009-06-10 13:36:04 -07002973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 synchronized(mWindowMap) {
2975 WindowToken wtoken = mTokenMap.get(token);
2976 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002977 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002978 return;
2979 }
2980 wtoken = new WindowToken(token, type, true);
2981 mTokenMap.put(token, wtoken);
2982 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002983 if (type == TYPE_WALLPAPER) {
2984 mWallpaperTokens.add(wtoken);
2985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 }
2987 }
Romain Guy06882f82009-06-10 13:36:04 -07002988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 public void removeWindowToken(IBinder token) {
2990 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2991 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002992 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002993 }
2994
2995 final long origId = Binder.clearCallingIdentity();
2996 synchronized(mWindowMap) {
2997 WindowToken wtoken = mTokenMap.remove(token);
2998 mTokenList.remove(wtoken);
2999 if (wtoken != null) {
3000 boolean delayed = false;
3001 if (!wtoken.hidden) {
3002 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 final int N = wtoken.windows.size();
3005 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003007 for (int i=0; i<N; i++) {
3008 WindowState win = wtoken.windows.get(i);
3009
3010 if (win.isAnimating()) {
3011 delayed = true;
3012 }
Romain Guy06882f82009-06-10 13:36:04 -07003013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003014 if (win.isVisibleNow()) {
3015 applyAnimationLocked(win,
3016 WindowManagerPolicy.TRANSIT_EXIT, false);
3017 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3018 KeyWaiter.RETURN_NOTHING);
3019 changed = true;
3020 }
3021 }
3022
3023 if (changed) {
3024 mLayoutNeeded = true;
3025 performLayoutAndPlaceSurfacesLocked();
3026 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3027 }
Romain Guy06882f82009-06-10 13:36:04 -07003028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003029 if (delayed) {
3030 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003031 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3032 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 }
3034 }
Romain Guy06882f82009-06-10 13:36:04 -07003035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003037 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 }
3039 }
3040 Binder.restoreCallingIdentity(origId);
3041 }
3042
3043 public void addAppToken(int addPos, IApplicationToken token,
3044 int groupId, int requestedOrientation, boolean fullscreen) {
3045 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3046 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003047 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 }
Romain Guy06882f82009-06-10 13:36:04 -07003049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003050 synchronized(mWindowMap) {
3051 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3052 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003053 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 return;
3055 }
3056 wtoken = new AppWindowToken(token);
3057 wtoken.groupId = groupId;
3058 wtoken.appFullscreen = fullscreen;
3059 wtoken.requestedOrientation = requestedOrientation;
3060 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003061 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 mTokenMap.put(token.asBinder(), wtoken);
3063 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065 // Application tokens start out hidden.
3066 wtoken.hidden = true;
3067 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 //dump();
3070 }
3071 }
Romain Guy06882f82009-06-10 13:36:04 -07003072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 public void setAppGroupId(IBinder token, int groupId) {
3074 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3075 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003076 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003077 }
3078
3079 synchronized(mWindowMap) {
3080 AppWindowToken wtoken = findAppWindowToken(token);
3081 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003082 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 return;
3084 }
3085 wtoken.groupId = groupId;
3086 }
3087 }
Romain Guy06882f82009-06-10 13:36:04 -07003088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 public int getOrientationFromWindowsLocked() {
3090 int pos = mWindows.size() - 1;
3091 while (pos >= 0) {
3092 WindowState wtoken = (WindowState) mWindows.get(pos);
3093 pos--;
3094 if (wtoken.mAppToken != null) {
3095 // We hit an application window. so the orientation will be determined by the
3096 // app window. No point in continuing further.
3097 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3098 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003099 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003100 continue;
3101 }
3102 int req = wtoken.mAttrs.screenOrientation;
3103 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3104 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3105 continue;
3106 } else {
3107 return req;
3108 }
3109 }
3110 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3111 }
Romain Guy06882f82009-06-10 13:36:04 -07003112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003114 int pos = mAppTokens.size() - 1;
3115 int curGroup = 0;
3116 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3117 boolean findingBehind = false;
3118 boolean haveGroup = false;
3119 boolean lastFullscreen = false;
3120 while (pos >= 0) {
3121 AppWindowToken wtoken = mAppTokens.get(pos);
3122 pos--;
3123 // if we're about to tear down this window and not seek for
3124 // the behind activity, don't use it for orientation
3125 if (!findingBehind
3126 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3127 continue;
3128 }
3129
3130 if (!haveGroup) {
3131 // We ignore any hidden applications on the top.
3132 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003133 continue;
3134 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003135 haveGroup = true;
3136 curGroup = wtoken.groupId;
3137 lastOrientation = wtoken.requestedOrientation;
3138 } else if (curGroup != wtoken.groupId) {
3139 // If we have hit a new application group, and the bottom
3140 // of the previous group didn't explicitly say to use
3141 // the orientation behind it, and the last app was
3142 // full screen, then we'll stick with the
3143 // user's orientation.
3144 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3145 && lastFullscreen) {
3146 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003149 int or = wtoken.requestedOrientation;
3150 // If this application is fullscreen, and didn't explicitly say
3151 // to use the orientation behind it, then just take whatever
3152 // orientation it has and ignores whatever is under it.
3153 lastFullscreen = wtoken.appFullscreen;
3154 if (lastFullscreen
3155 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3156 return or;
3157 }
3158 // If this application has requested an explicit orientation,
3159 // then use it.
3160 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3161 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3162 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3163 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3164 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3165 return or;
3166 }
3167 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3168 }
3169 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003170 }
Romain Guy06882f82009-06-10 13:36:04 -07003171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003173 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003174 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3175 "updateOrientationFromAppTokens()")) {
3176 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3177 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003178
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003179 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003180 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003181
3182 synchronized(mWindowMap) {
3183 if (updateOrientationFromAppTokensLocked()) {
3184 if (freezeThisOneIfNeeded != null) {
3185 AppWindowToken wtoken = findAppWindowToken(
3186 freezeThisOneIfNeeded);
3187 if (wtoken != null) {
3188 startAppFreezingScreenLocked(wtoken,
3189 ActivityInfo.CONFIG_ORIENTATION);
3190 }
3191 }
3192 config = computeNewConfigurationLocked();
3193
3194 } else if (currentConfig != null) {
3195 // No obvious action we need to take, but if our current
3196 // state mismatches the activity maanager's, update it
3197 mTempConfiguration.setToDefaults();
3198 if (computeNewConfigurationLocked(mTempConfiguration)) {
3199 if (currentConfig.diff(mTempConfiguration) != 0) {
3200 mWaitingForConfig = true;
3201 mLayoutNeeded = true;
3202 startFreezingDisplayLocked();
3203 config = new Configuration(mTempConfiguration);
3204 }
3205 }
3206 }
3207 }
3208
Dianne Hackborncfaef692009-06-15 14:24:44 -07003209 Binder.restoreCallingIdentity(ident);
3210 return config;
3211 }
3212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003214 * Determine the new desired orientation of the display, returning
3215 * a non-null new Configuration if it has changed from the current
3216 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3217 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3218 * SCREEN. This will typically be done for you if you call
3219 * sendNewConfiguration().
3220 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003221 * The orientation is computed from non-application windows first. If none of
3222 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003223 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3225 * android.os.IBinder)
3226 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003227 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003228 if (mDisplayFrozen) {
3229 // If the display is frozen, some activities may be in the middle
3230 // of restarting, and thus have removed their old window. If the
3231 // window has the flag to hide the lock screen, then the lock screen
3232 // can re-appear and inflict its own orientation on us. Keep the
3233 // orientation stable until this all settles down.
3234 return false;
3235 }
3236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003238 long ident = Binder.clearCallingIdentity();
3239 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003240 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003242 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003243 mForcedAppOrientation = req;
3244 //send a message to Policy indicating orientation change to take
3245 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003246 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003247 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3248 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3249 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250 }
3251 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003252
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003253 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 } finally {
3255 Binder.restoreCallingIdentity(ident);
3256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003257 }
Romain Guy06882f82009-06-10 13:36:04 -07003258
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003259 int computeForcedAppOrientationLocked() {
3260 int req = getOrientationFromWindowsLocked();
3261 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3262 req = getOrientationFromAppTokensLocked();
3263 }
3264 return req;
3265 }
Romain Guy06882f82009-06-10 13:36:04 -07003266
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003267 public void setNewConfiguration(Configuration config) {
3268 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3269 "setNewConfiguration()")) {
3270 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3271 }
3272
3273 synchronized(mWindowMap) {
3274 mCurConfiguration = new Configuration(config);
3275 mWaitingForConfig = false;
3276 performLayoutAndPlaceSurfacesLocked();
3277 }
3278 }
3279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3281 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3282 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003283 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 }
Romain Guy06882f82009-06-10 13:36:04 -07003285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003286 synchronized(mWindowMap) {
3287 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3288 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003289 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 return;
3291 }
Romain Guy06882f82009-06-10 13:36:04 -07003292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 wtoken.requestedOrientation = requestedOrientation;
3294 }
3295 }
Romain Guy06882f82009-06-10 13:36:04 -07003296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003297 public int getAppOrientation(IApplicationToken token) {
3298 synchronized(mWindowMap) {
3299 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3300 if (wtoken == null) {
3301 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3302 }
Romain Guy06882f82009-06-10 13:36:04 -07003303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304 return wtoken.requestedOrientation;
3305 }
3306 }
Romain Guy06882f82009-06-10 13:36:04 -07003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3309 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3310 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003311 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 }
3313
3314 synchronized(mWindowMap) {
3315 boolean changed = false;
3316 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003317 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 changed = mFocusedApp != null;
3319 mFocusedApp = null;
3320 mKeyWaiter.tickle();
3321 } else {
3322 AppWindowToken newFocus = findAppWindowToken(token);
3323 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003324 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 return;
3326 }
3327 changed = mFocusedApp != newFocus;
3328 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003329 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 mKeyWaiter.tickle();
3331 }
3332
3333 if (moveFocusNow && changed) {
3334 final long origId = Binder.clearCallingIdentity();
3335 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3336 Binder.restoreCallingIdentity(origId);
3337 }
3338 }
3339 }
3340
3341 public void prepareAppTransition(int transit) {
3342 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3343 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003344 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 }
Romain Guy06882f82009-06-10 13:36:04 -07003346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003347 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003348 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 TAG, "Prepare app transition: transit=" + transit
3350 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003351 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003352 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3353 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003355 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3356 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3357 // Opening a new task always supersedes a close for the anim.
3358 mNextAppTransition = transit;
3359 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3360 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3361 // Opening a new activity always supersedes a close for the anim.
3362 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003363 }
3364 mAppTransitionReady = false;
3365 mAppTransitionTimeout = false;
3366 mStartingIconInTransition = false;
3367 mSkipAppTransitionAnimation = false;
3368 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3369 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3370 5000);
3371 }
3372 }
3373 }
3374
3375 public int getPendingAppTransition() {
3376 return mNextAppTransition;
3377 }
Romain Guy06882f82009-06-10 13:36:04 -07003378
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003379 public void overridePendingAppTransition(String packageName,
3380 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003381 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003382 mNextAppTransitionPackage = packageName;
3383 mNextAppTransitionEnter = enterAnim;
3384 mNextAppTransitionExit = exitAnim;
3385 }
3386 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 public void executeAppTransition() {
3389 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3390 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003391 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 }
Romain Guy06882f82009-06-10 13:36:04 -07003393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003395 if (DEBUG_APP_TRANSITIONS) {
3396 RuntimeException e = new RuntimeException("here");
3397 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003398 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003399 + mNextAppTransition, e);
3400 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003401 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 mAppTransitionReady = true;
3403 final long origId = Binder.clearCallingIdentity();
3404 performLayoutAndPlaceSurfacesLocked();
3405 Binder.restoreCallingIdentity(origId);
3406 }
3407 }
3408 }
3409
3410 public void setAppStartingWindow(IBinder token, String pkg,
3411 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3412 IBinder transferFrom, boolean createIfNeeded) {
3413 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3414 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003415 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 }
3417
3418 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003419 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3421 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003423 AppWindowToken wtoken = findAppWindowToken(token);
3424 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003425 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 return;
3427 }
3428
3429 // If the display is frozen, we won't do anything until the
3430 // actual window is displayed so there is no reason to put in
3431 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003432 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 return;
3434 }
Romain Guy06882f82009-06-10 13:36:04 -07003435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003436 if (wtoken.startingData != null) {
3437 return;
3438 }
Romain Guy06882f82009-06-10 13:36:04 -07003439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003440 if (transferFrom != null) {
3441 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3442 if (ttoken != null) {
3443 WindowState startingWindow = ttoken.startingWindow;
3444 if (startingWindow != null) {
3445 if (mStartingIconInTransition) {
3446 // In this case, the starting icon has already
3447 // been displayed, so start letting windows get
3448 // shown immediately without any more transitions.
3449 mSkipAppTransitionAnimation = true;
3450 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003451 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 "Moving existing starting from " + ttoken
3453 + " to " + wtoken);
3454 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 // Transfer the starting window over to the new
3457 // token.
3458 wtoken.startingData = ttoken.startingData;
3459 wtoken.startingView = ttoken.startingView;
3460 wtoken.startingWindow = startingWindow;
3461 ttoken.startingData = null;
3462 ttoken.startingView = null;
3463 ttoken.startingWindow = null;
3464 ttoken.startingMoved = true;
3465 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003466 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003467 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003468 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003469 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 mWindows.remove(startingWindow);
3471 ttoken.windows.remove(startingWindow);
3472 ttoken.allAppWindows.remove(startingWindow);
3473 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 // Propagate other interesting state between the
3476 // tokens. If the old token is displayed, we should
3477 // immediately force the new one to be displayed. If
3478 // it is animating, we need to move that animation to
3479 // the new one.
3480 if (ttoken.allDrawn) {
3481 wtoken.allDrawn = true;
3482 }
3483 if (ttoken.firstWindowDrawn) {
3484 wtoken.firstWindowDrawn = true;
3485 }
3486 if (!ttoken.hidden) {
3487 wtoken.hidden = false;
3488 wtoken.hiddenRequested = false;
3489 wtoken.willBeHidden = false;
3490 }
3491 if (wtoken.clientHidden != ttoken.clientHidden) {
3492 wtoken.clientHidden = ttoken.clientHidden;
3493 wtoken.sendAppVisibilityToClients();
3494 }
3495 if (ttoken.animation != null) {
3496 wtoken.animation = ttoken.animation;
3497 wtoken.animating = ttoken.animating;
3498 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3499 ttoken.animation = null;
3500 ttoken.animLayerAdjustment = 0;
3501 wtoken.updateLayers();
3502 ttoken.updateLayers();
3503 }
Romain Guy06882f82009-06-10 13:36:04 -07003504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 mLayoutNeeded = true;
3507 performLayoutAndPlaceSurfacesLocked();
3508 Binder.restoreCallingIdentity(origId);
3509 return;
3510 } else if (ttoken.startingData != null) {
3511 // The previous app was getting ready to show a
3512 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003513 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 "Moving pending starting from " + ttoken
3515 + " to " + wtoken);
3516 wtoken.startingData = ttoken.startingData;
3517 ttoken.startingData = null;
3518 ttoken.startingMoved = true;
3519 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3520 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3521 // want to process the message ASAP, before any other queued
3522 // messages.
3523 mH.sendMessageAtFrontOfQueue(m);
3524 return;
3525 }
3526 }
3527 }
3528
3529 // There is no existing starting window, and the caller doesn't
3530 // want us to create one, so that's it!
3531 if (!createIfNeeded) {
3532 return;
3533 }
Romain Guy06882f82009-06-10 13:36:04 -07003534
Dianne Hackborn284ac932009-08-28 10:34:25 -07003535 // If this is a translucent or wallpaper window, then don't
3536 // show a starting window -- the current effect (a full-screen
3537 // opaque starting window that fades away to the real contents
3538 // when it is ready) does not work for this.
3539 if (theme != 0) {
3540 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3541 com.android.internal.R.styleable.Window);
3542 if (ent.array.getBoolean(
3543 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3544 return;
3545 }
3546 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003547 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3548 return;
3549 }
3550 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003551 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3552 return;
3553 }
3554 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 mStartingIconInTransition = true;
3557 wtoken.startingData = new StartingData(
3558 pkg, theme, nonLocalizedLabel,
3559 labelRes, icon);
3560 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3561 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3562 // want to process the message ASAP, before any other queued
3563 // messages.
3564 mH.sendMessageAtFrontOfQueue(m);
3565 }
3566 }
3567
3568 public void setAppWillBeHidden(IBinder token) {
3569 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3570 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003571 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 }
3573
3574 AppWindowToken wtoken;
3575
3576 synchronized(mWindowMap) {
3577 wtoken = findAppWindowToken(token);
3578 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003579 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 -08003580 return;
3581 }
3582 wtoken.willBeHidden = true;
3583 }
3584 }
Romain Guy06882f82009-06-10 13:36:04 -07003585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3587 boolean visible, int transit, boolean performLayout) {
3588 boolean delayed = false;
3589
3590 if (wtoken.clientHidden == visible) {
3591 wtoken.clientHidden = !visible;
3592 wtoken.sendAppVisibilityToClients();
3593 }
Romain Guy06882f82009-06-10 13:36:04 -07003594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 wtoken.willBeHidden = false;
3596 if (wtoken.hidden == visible) {
3597 final int N = wtoken.allAppWindows.size();
3598 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003599 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3601 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003604
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003605 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 if (wtoken.animation == sDummyAnimation) {
3607 wtoken.animation = null;
3608 }
3609 applyAnimationLocked(wtoken, lp, transit, visible);
3610 changed = true;
3611 if (wtoken.animation != null) {
3612 delayed = runningAppAnimation = true;
3613 }
3614 }
Romain Guy06882f82009-06-10 13:36:04 -07003615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 for (int i=0; i<N; i++) {
3617 WindowState win = wtoken.allAppWindows.get(i);
3618 if (win == wtoken.startingWindow) {
3619 continue;
3620 }
3621
3622 if (win.isAnimating()) {
3623 delayed = true;
3624 }
Romain Guy06882f82009-06-10 13:36:04 -07003625
Joe Onorato8a9b2202010-02-26 18:56:32 -08003626 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627 //win.dump(" ");
3628 if (visible) {
3629 if (!win.isVisibleNow()) {
3630 if (!runningAppAnimation) {
3631 applyAnimationLocked(win,
3632 WindowManagerPolicy.TRANSIT_ENTER, true);
3633 }
3634 changed = true;
3635 }
3636 } else if (win.isVisibleNow()) {
3637 if (!runningAppAnimation) {
3638 applyAnimationLocked(win,
3639 WindowManagerPolicy.TRANSIT_EXIT, false);
3640 }
3641 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3642 KeyWaiter.RETURN_NOTHING);
3643 changed = true;
3644 }
3645 }
3646
3647 wtoken.hidden = wtoken.hiddenRequested = !visible;
3648 if (!visible) {
3649 unsetAppFreezingScreenLocked(wtoken, true, true);
3650 } else {
3651 // If we are being set visible, and the starting window is
3652 // not yet displayed, then make sure it doesn't get displayed.
3653 WindowState swin = wtoken.startingWindow;
3654 if (swin != null && (swin.mDrawPending
3655 || swin.mCommitDrawPending)) {
3656 swin.mPolicyVisibility = false;
3657 swin.mPolicyVisibilityAfterAnim = false;
3658 }
3659 }
Romain Guy06882f82009-06-10 13:36:04 -07003660
Joe Onorato8a9b2202010-02-26 18:56:32 -08003661 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3663 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003664
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003665 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003667 if (performLayout) {
3668 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3669 performLayoutAndPlaceSurfacesLocked();
3670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 }
3672 }
3673
3674 if (wtoken.animation != null) {
3675 delayed = true;
3676 }
Romain Guy06882f82009-06-10 13:36:04 -07003677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 return delayed;
3679 }
3680
3681 public void setAppVisibility(IBinder token, boolean visible) {
3682 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3683 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003684 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 }
3686
3687 AppWindowToken wtoken;
3688
3689 synchronized(mWindowMap) {
3690 wtoken = findAppWindowToken(token);
3691 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003692 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 return;
3694 }
3695
3696 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003697 RuntimeException e = null;
3698 if (!HIDE_STACK_CRAWLS) {
3699 e = new RuntimeException();
3700 e.fillInStackTrace();
3701 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003702 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 + "): mNextAppTransition=" + mNextAppTransition
3704 + " hidden=" + wtoken.hidden
3705 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3706 }
Romain Guy06882f82009-06-10 13:36:04 -07003707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 // If we are preparing an app transition, then delay changing
3709 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003710 if (!mDisplayFrozen && mPolicy.isScreenOn()
3711 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 // Already in requested state, don't do anything more.
3713 if (wtoken.hiddenRequested != visible) {
3714 return;
3715 }
3716 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003717
Joe Onorato8a9b2202010-02-26 18:56:32 -08003718 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 TAG, "Setting dummy animation on: " + wtoken);
3720 wtoken.setDummyAnimation();
3721 mOpeningApps.remove(wtoken);
3722 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003723 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 wtoken.inPendingTransaction = true;
3725 if (visible) {
3726 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 wtoken.startingDisplayed = false;
3728 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003729
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003730 // If the token is currently hidden (should be the
3731 // common case), then we need to set up to wait for
3732 // its windows to be ready.
3733 if (wtoken.hidden) {
3734 wtoken.allDrawn = false;
3735 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003736
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003737 if (wtoken.clientHidden) {
3738 // In the case where we are making an app visible
3739 // but holding off for a transition, we still need
3740 // to tell the client to make its windows visible so
3741 // they get drawn. Otherwise, we will wait on
3742 // performing the transition until all windows have
3743 // been drawn, they never will be, and we are sad.
3744 wtoken.clientHidden = false;
3745 wtoken.sendAppVisibilityToClients();
3746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 }
3748 } else {
3749 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003750
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003751 // If the token is currently visible (should be the
3752 // common case), then set up to wait for it to be hidden.
3753 if (!wtoken.hidden) {
3754 wtoken.waitingToHide = true;
3755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 }
3757 return;
3758 }
Romain Guy06882f82009-06-10 13:36:04 -07003759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003761 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 wtoken.updateReportedVisibilityLocked();
3763 Binder.restoreCallingIdentity(origId);
3764 }
3765 }
3766
3767 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3768 boolean unfreezeSurfaceNow, boolean force) {
3769 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003770 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 + " force=" + force);
3772 final int N = wtoken.allAppWindows.size();
3773 boolean unfrozeWindows = false;
3774 for (int i=0; i<N; i++) {
3775 WindowState w = wtoken.allAppWindows.get(i);
3776 if (w.mAppFreezing) {
3777 w.mAppFreezing = false;
3778 if (w.mSurface != null && !w.mOrientationChanging) {
3779 w.mOrientationChanging = true;
3780 }
3781 unfrozeWindows = true;
3782 }
3783 }
3784 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003785 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 wtoken.freezingScreen = false;
3787 mAppsFreezingScreen--;
3788 }
3789 if (unfreezeSurfaceNow) {
3790 if (unfrozeWindows) {
3791 mLayoutNeeded = true;
3792 performLayoutAndPlaceSurfacesLocked();
3793 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003794 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
3796 }
3797 }
Romain Guy06882f82009-06-10 13:36:04 -07003798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3800 int configChanges) {
3801 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003802 RuntimeException e = null;
3803 if (!HIDE_STACK_CRAWLS) {
3804 e = new RuntimeException();
3805 e.fillInStackTrace();
3806 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003807 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 + ": hidden=" + wtoken.hidden + " freezing="
3809 + wtoken.freezingScreen, e);
3810 }
3811 if (!wtoken.hiddenRequested) {
3812 if (!wtoken.freezingScreen) {
3813 wtoken.freezingScreen = true;
3814 mAppsFreezingScreen++;
3815 if (mAppsFreezingScreen == 1) {
3816 startFreezingDisplayLocked();
3817 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3818 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3819 5000);
3820 }
3821 }
3822 final int N = wtoken.allAppWindows.size();
3823 for (int i=0; i<N; i++) {
3824 WindowState w = wtoken.allAppWindows.get(i);
3825 w.mAppFreezing = true;
3826 }
3827 }
3828 }
Romain Guy06882f82009-06-10 13:36:04 -07003829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 public void startAppFreezingScreen(IBinder token, int configChanges) {
3831 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3832 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003833 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 }
3835
3836 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003837 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003838 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 return;
3840 }
Romain Guy06882f82009-06-10 13:36:04 -07003841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 AppWindowToken wtoken = findAppWindowToken(token);
3843 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003844 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 return;
3846 }
3847 final long origId = Binder.clearCallingIdentity();
3848 startAppFreezingScreenLocked(wtoken, configChanges);
3849 Binder.restoreCallingIdentity(origId);
3850 }
3851 }
Romain Guy06882f82009-06-10 13:36:04 -07003852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003853 public void stopAppFreezingScreen(IBinder token, boolean force) {
3854 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3855 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003856 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857 }
3858
3859 synchronized(mWindowMap) {
3860 AppWindowToken wtoken = findAppWindowToken(token);
3861 if (wtoken == null || wtoken.appToken == null) {
3862 return;
3863 }
3864 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003865 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003866 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3867 unsetAppFreezingScreenLocked(wtoken, true, force);
3868 Binder.restoreCallingIdentity(origId);
3869 }
3870 }
Romain Guy06882f82009-06-10 13:36:04 -07003871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 public void removeAppToken(IBinder token) {
3873 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3874 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003875 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 }
3877
3878 AppWindowToken wtoken = null;
3879 AppWindowToken startingToken = null;
3880 boolean delayed = false;
3881
3882 final long origId = Binder.clearCallingIdentity();
3883 synchronized(mWindowMap) {
3884 WindowToken basewtoken = mTokenMap.remove(token);
3885 mTokenList.remove(basewtoken);
3886 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003887 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003888 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 wtoken.inPendingTransaction = false;
3890 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003891 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 if (mClosingApps.contains(wtoken)) {
3893 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003894 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003896 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 delayed = true;
3898 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003899 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 TAG, "Removing app " + wtoken + " delayed=" + delayed
3901 + " animation=" + wtoken.animation
3902 + " animating=" + wtoken.animating);
3903 if (delayed) {
3904 // set the token aside because it has an active animation to be finished
3905 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003906 } else {
3907 // Make sure there is no animation running on this token,
3908 // so any windows associated with it will be removed as
3909 // soon as their animations are complete
3910 wtoken.animation = null;
3911 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 }
3913 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003914 if (mLastEnterAnimToken == wtoken) {
3915 mLastEnterAnimToken = null;
3916 mLastEnterAnimParams = null;
3917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 wtoken.removed = true;
3919 if (wtoken.startingData != null) {
3920 startingToken = wtoken;
3921 }
3922 unsetAppFreezingScreenLocked(wtoken, true, true);
3923 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003924 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 mFocusedApp = null;
3926 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3927 mKeyWaiter.tickle();
3928 }
3929 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003930 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 }
Romain Guy06882f82009-06-10 13:36:04 -07003932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 if (!delayed && wtoken != null) {
3934 wtoken.updateReportedVisibilityLocked();
3935 }
3936 }
3937 Binder.restoreCallingIdentity(origId);
3938
3939 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003940 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 + startingToken + ": app token removed");
3942 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3943 mH.sendMessage(m);
3944 }
3945 }
3946
3947 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3948 final int NW = token.windows.size();
3949 for (int i=0; i<NW; i++) {
3950 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003951 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 mWindows.remove(win);
3953 int j = win.mChildWindows.size();
3954 while (j > 0) {
3955 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003956 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003957 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07003958 "Tmp removing child window " + cwin);
3959 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 }
3961 }
3962 return NW > 0;
3963 }
3964
3965 void dumpAppTokensLocked() {
3966 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003967 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
3969 }
Romain Guy06882f82009-06-10 13:36:04 -07003970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 void dumpWindowsLocked() {
3972 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003973 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003974 }
3975 }
Romain Guy06882f82009-06-10 13:36:04 -07003976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 private int findWindowOffsetLocked(int tokenPos) {
3978 final int NW = mWindows.size();
3979
3980 if (tokenPos >= mAppTokens.size()) {
3981 int i = NW;
3982 while (i > 0) {
3983 i--;
3984 WindowState win = (WindowState)mWindows.get(i);
3985 if (win.getAppToken() != null) {
3986 return i+1;
3987 }
3988 }
3989 }
3990
3991 while (tokenPos > 0) {
3992 // Find the first app token below the new position that has
3993 // a window displayed.
3994 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003995 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003997 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003998 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07003999 "Skipping token -- currently sending to bottom");
4000 tokenPos--;
4001 continue;
4002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 int i = wtoken.windows.size();
4004 while (i > 0) {
4005 i--;
4006 WindowState win = wtoken.windows.get(i);
4007 int j = win.mChildWindows.size();
4008 while (j > 0) {
4009 j--;
4010 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004011 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 for (int pos=NW-1; pos>=0; pos--) {
4013 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004014 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 "Found child win @" + (pos+1));
4016 return pos+1;
4017 }
4018 }
4019 }
4020 }
4021 for (int pos=NW-1; pos>=0; pos--) {
4022 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 return pos+1;
4025 }
4026 }
4027 }
4028 tokenPos--;
4029 }
4030
4031 return 0;
4032 }
4033
4034 private final int reAddWindowLocked(int index, WindowState win) {
4035 final int NCW = win.mChildWindows.size();
4036 boolean added = false;
4037 for (int j=0; j<NCW; j++) {
4038 WindowState cwin = (WindowState)win.mChildWindows.get(j);
4039 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004040 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004041 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 mWindows.add(index, win);
4043 index++;
4044 added = true;
4045 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004046 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004047 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 mWindows.add(index, cwin);
4049 index++;
4050 }
4051 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004052 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004053 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 mWindows.add(index, win);
4055 index++;
4056 }
4057 return index;
4058 }
Romain Guy06882f82009-06-10 13:36:04 -07004059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004060 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4061 final int NW = token.windows.size();
4062 for (int i=0; i<NW; i++) {
4063 index = reAddWindowLocked(index, token.windows.get(i));
4064 }
4065 return index;
4066 }
4067
4068 public void moveAppToken(int index, IBinder token) {
4069 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4070 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004071 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 }
4073
4074 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004075 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 if (DEBUG_REORDER) dumpAppTokensLocked();
4077 final AppWindowToken wtoken = findAppWindowToken(token);
4078 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004079 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 + token + " (" + wtoken + ")");
4081 return;
4082 }
4083 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004084 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004088 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 if (DEBUG_REORDER) dumpWindowsLocked();
4090 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004091 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 if (DEBUG_REORDER) dumpWindowsLocked();
4093 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004094 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 if (DEBUG_REORDER) dumpWindowsLocked();
4096 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 mLayoutNeeded = true;
4098 performLayoutAndPlaceSurfacesLocked();
4099 }
4100 Binder.restoreCallingIdentity(origId);
4101 }
4102 }
4103
4104 private void removeAppTokensLocked(List<IBinder> tokens) {
4105 // XXX This should be done more efficiently!
4106 // (take advantage of the fact that both lists should be
4107 // ordered in the same way.)
4108 int N = tokens.size();
4109 for (int i=0; i<N; i++) {
4110 IBinder token = tokens.get(i);
4111 final AppWindowToken wtoken = findAppWindowToken(token);
4112 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004113 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 + token + " (" + wtoken + ")");
4115 i--;
4116 N--;
4117 }
4118 }
4119 }
4120
Dianne Hackborna8f60182009-09-01 19:01:50 -07004121 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4122 boolean updateFocusAndLayout) {
4123 // First remove all of the windows from the list.
4124 tmpRemoveAppWindowsLocked(wtoken);
4125
4126 // Where to start adding?
4127 int pos = findWindowOffsetLocked(tokenPos);
4128
4129 // And now add them back at the correct place.
4130 pos = reAddAppWindowsLocked(pos, wtoken);
4131
4132 if (updateFocusAndLayout) {
4133 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4134 assignLayersLocked();
4135 }
4136 mLayoutNeeded = true;
4137 performLayoutAndPlaceSurfacesLocked();
4138 }
4139 }
4140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4142 // First remove all of the windows from the list.
4143 final int N = tokens.size();
4144 int i;
4145 for (i=0; i<N; i++) {
4146 WindowToken token = mTokenMap.get(tokens.get(i));
4147 if (token != null) {
4148 tmpRemoveAppWindowsLocked(token);
4149 }
4150 }
4151
4152 // Where to start adding?
4153 int pos = findWindowOffsetLocked(tokenPos);
4154
4155 // And now add them back at the correct place.
4156 for (i=0; i<N; i++) {
4157 WindowToken token = mTokenMap.get(tokens.get(i));
4158 if (token != null) {
4159 pos = reAddAppWindowsLocked(pos, token);
4160 }
4161 }
4162
Dianne Hackborna8f60182009-09-01 19:01:50 -07004163 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4164 assignLayersLocked();
4165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 mLayoutNeeded = true;
4167 performLayoutAndPlaceSurfacesLocked();
4168
4169 //dump();
4170 }
4171
4172 public void moveAppTokensToTop(List<IBinder> tokens) {
4173 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4174 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004175 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
4177
4178 final long origId = Binder.clearCallingIdentity();
4179 synchronized(mWindowMap) {
4180 removeAppTokensLocked(tokens);
4181 final int N = tokens.size();
4182 for (int i=0; i<N; i++) {
4183 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4184 if (wt != null) {
4185 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004186 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004187 mToTopApps.remove(wt);
4188 mToBottomApps.remove(wt);
4189 mToTopApps.add(wt);
4190 wt.sendingToBottom = false;
4191 wt.sendingToTop = true;
4192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 }
4194 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004195
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004196 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004197 moveAppWindowsLocked(tokens, mAppTokens.size());
4198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 }
4200 Binder.restoreCallingIdentity(origId);
4201 }
4202
4203 public void moveAppTokensToBottom(List<IBinder> tokens) {
4204 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4205 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004206 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 }
4208
4209 final long origId = Binder.clearCallingIdentity();
4210 synchronized(mWindowMap) {
4211 removeAppTokensLocked(tokens);
4212 final int N = tokens.size();
4213 int pos = 0;
4214 for (int i=0; i<N; i++) {
4215 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4216 if (wt != null) {
4217 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004218 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004219 mToTopApps.remove(wt);
4220 mToBottomApps.remove(wt);
4221 mToBottomApps.add(i, wt);
4222 wt.sendingToTop = false;
4223 wt.sendingToBottom = true;
4224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 pos++;
4226 }
4227 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004228
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004229 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004230 moveAppWindowsLocked(tokens, 0);
4231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004232 }
4233 Binder.restoreCallingIdentity(origId);
4234 }
4235
4236 // -------------------------------------------------------------
4237 // Misc IWindowSession methods
4238 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004239
Jim Miller284b62e2010-06-08 14:27:42 -07004240 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004241 {
Jim Miller284b62e2010-06-08 14:27:42 -07004242 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4243 // called before DevicePolicyManagerService has started.
4244 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4245 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4246 Context.DEVICE_POLICY_SERVICE);
4247 if (dpm != null) {
4248 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4249 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4250 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4251 }
Jim Millerd6b57052010-06-07 17:52:42 -07004252 }
Jim Miller284b62e2010-06-08 14:27:42 -07004253 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004254 }
4255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004257 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 != PackageManager.PERMISSION_GRANTED) {
4259 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4260 }
Jim Millerd6b57052010-06-07 17:52:42 -07004261
Jim Miller284b62e2010-06-08 14:27:42 -07004262 synchronized (mKeyguardTokenWatcher) {
4263 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 }
4266
4267 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004268 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 != PackageManager.PERMISSION_GRANTED) {
4270 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272
Jim Miller284b62e2010-06-08 14:27:42 -07004273 synchronized (mKeyguardTokenWatcher) {
4274 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004275
Jim Miller284b62e2010-06-08 14:27:42 -07004276 if (!mKeyguardTokenWatcher.isAcquired()) {
4277 // If we are the last one to reenable the keyguard wait until
4278 // we have actually finished reenabling until returning.
4279 // It is possible that reenableKeyguard() can be called before
4280 // the previous disableKeyguard() is handled, in which case
4281 // neither mKeyguardTokenWatcher.acquired() or released() would
4282 // be called. In that case mKeyguardDisabled will be false here
4283 // and we have nothing to wait for.
4284 while (mKeyguardDisabled) {
4285 try {
4286 mKeyguardTokenWatcher.wait();
4287 } catch (InterruptedException e) {
4288 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 }
4290 }
4291 }
4292 }
4293 }
4294
4295 /**
4296 * @see android.app.KeyguardManager#exitKeyguardSecurely
4297 */
4298 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004299 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 != PackageManager.PERMISSION_GRANTED) {
4301 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4302 }
4303 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4304 public void onKeyguardExitResult(boolean success) {
4305 try {
4306 callback.onKeyguardExitResult(success);
4307 } catch (RemoteException e) {
4308 // Client has died, we don't care.
4309 }
4310 }
4311 });
4312 }
4313
4314 public boolean inKeyguardRestrictedInputMode() {
4315 return mPolicy.inKeyguardRestrictedKeyInputMode();
4316 }
Romain Guy06882f82009-06-10 13:36:04 -07004317
Dianne Hackbornffa42482009-09-23 22:20:11 -07004318 public void closeSystemDialogs(String reason) {
4319 synchronized(mWindowMap) {
4320 for (int i=mWindows.size()-1; i>=0; i--) {
4321 WindowState w = (WindowState)mWindows.get(i);
4322 if (w.mSurface != null) {
4323 try {
4324 w.mClient.closeSystemDialogs(reason);
4325 } catch (RemoteException e) {
4326 }
4327 }
4328 }
4329 }
4330 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 static float fixScale(float scale) {
4333 if (scale < 0) scale = 0;
4334 else if (scale > 20) scale = 20;
4335 return Math.abs(scale);
4336 }
Romain Guy06882f82009-06-10 13:36:04 -07004337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 public void setAnimationScale(int which, float scale) {
4339 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4340 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004341 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 }
4343
4344 if (scale < 0) scale = 0;
4345 else if (scale > 20) scale = 20;
4346 scale = Math.abs(scale);
4347 switch (which) {
4348 case 0: mWindowAnimationScale = fixScale(scale); break;
4349 case 1: mTransitionAnimationScale = fixScale(scale); break;
4350 }
Romain Guy06882f82009-06-10 13:36:04 -07004351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 // Persist setting
4353 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4354 }
Romain Guy06882f82009-06-10 13:36:04 -07004355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 public void setAnimationScales(float[] scales) {
4357 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4358 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004359 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
4361
4362 if (scales != null) {
4363 if (scales.length >= 1) {
4364 mWindowAnimationScale = fixScale(scales[0]);
4365 }
4366 if (scales.length >= 2) {
4367 mTransitionAnimationScale = fixScale(scales[1]);
4368 }
4369 }
Romain Guy06882f82009-06-10 13:36:04 -07004370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 // Persist setting
4372 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4373 }
Romain Guy06882f82009-06-10 13:36:04 -07004374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004375 public float getAnimationScale(int which) {
4376 switch (which) {
4377 case 0: return mWindowAnimationScale;
4378 case 1: return mTransitionAnimationScale;
4379 }
4380 return 0;
4381 }
Romain Guy06882f82009-06-10 13:36:04 -07004382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 public float[] getAnimationScales() {
4384 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4385 }
Romain Guy06882f82009-06-10 13:36:04 -07004386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 public int getSwitchState(int sw) {
4388 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4389 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004390 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004392 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4393 return mInputManager.getSwitchState(sw);
4394 } else {
4395 return KeyInputQueue.getSwitchState(sw);
4396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
Romain Guy06882f82009-06-10 13:36:04 -07004398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 public int getSwitchStateForDevice(int devid, int sw) {
4400 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4401 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004402 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004404 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4405 return mInputManager.getSwitchState(devid, sw);
4406 } else {
4407 return KeyInputQueue.getSwitchState(devid, sw);
4408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 }
Romain Guy06882f82009-06-10 13:36:04 -07004410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 public int getScancodeState(int sw) {
4412 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4413 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004414 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004416 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4417 return mInputManager.getScancodeState(sw);
4418 } else {
4419 return mQueue.getScancodeState(sw);
4420 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 }
Romain Guy06882f82009-06-10 13:36:04 -07004422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 public int getScancodeStateForDevice(int devid, int sw) {
4424 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4425 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004426 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004428 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4429 return mInputManager.getScancodeState(devid, sw);
4430 } else {
4431 return mQueue.getScancodeState(devid, sw);
4432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 }
Romain Guy06882f82009-06-10 13:36:04 -07004434
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004435 public int getTrackballScancodeState(int sw) {
4436 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4437 "getTrackballScancodeState()")) {
4438 throw new SecurityException("Requires READ_INPUT_STATE permission");
4439 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004440 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4441 return mInputManager.getTrackballScancodeState(sw);
4442 } else {
4443 return mQueue.getTrackballScancodeState(sw);
4444 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004445 }
4446
4447 public int getDPadScancodeState(int sw) {
4448 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4449 "getDPadScancodeState()")) {
4450 throw new SecurityException("Requires READ_INPUT_STATE permission");
4451 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004452 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4453 return mInputManager.getDPadScancodeState(sw);
4454 } else {
4455 return mQueue.getDPadScancodeState(sw);
4456 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004457 }
4458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 public int getKeycodeState(int sw) {
4460 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4461 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004462 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004464 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4465 return mInputManager.getKeycodeState(sw);
4466 } else {
4467 return mQueue.getKeycodeState(sw);
4468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 }
Romain Guy06882f82009-06-10 13:36:04 -07004470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471 public int getKeycodeStateForDevice(int devid, int sw) {
4472 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4473 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004474 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004476 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4477 return mInputManager.getKeycodeState(devid, sw);
4478 } else {
4479 return mQueue.getKeycodeState(devid, sw);
4480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
Romain Guy06882f82009-06-10 13:36:04 -07004482
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004483 public int getTrackballKeycodeState(int sw) {
4484 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4485 "getTrackballKeycodeState()")) {
4486 throw new SecurityException("Requires READ_INPUT_STATE permission");
4487 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004488 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4489 return mInputManager.getTrackballKeycodeState(sw);
4490 } else {
4491 return mQueue.getTrackballKeycodeState(sw);
4492 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004493 }
4494
4495 public int getDPadKeycodeState(int sw) {
4496 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4497 "getDPadKeycodeState()")) {
4498 throw new SecurityException("Requires READ_INPUT_STATE permission");
4499 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004500 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4501 return mInputManager.getDPadKeycodeState(sw);
4502 } else {
4503 return mQueue.getDPadKeycodeState(sw);
4504 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004505 }
4506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004508 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4509 return mInputManager.hasKeys(keycodes, keyExists);
4510 } else {
4511 return KeyInputQueue.hasKeys(keycodes, keyExists);
4512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 }
Romain Guy06882f82009-06-10 13:36:04 -07004514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515 public void enableScreenAfterBoot() {
4516 synchronized(mWindowMap) {
4517 if (mSystemBooted) {
4518 return;
4519 }
4520 mSystemBooted = true;
4521 }
Romain Guy06882f82009-06-10 13:36:04 -07004522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 performEnableScreen();
4524 }
Romain Guy06882f82009-06-10 13:36:04 -07004525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 public void enableScreenIfNeededLocked() {
4527 if (mDisplayEnabled) {
4528 return;
4529 }
4530 if (!mSystemBooted) {
4531 return;
4532 }
4533 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4534 }
Romain Guy06882f82009-06-10 13:36:04 -07004535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 public void performEnableScreen() {
4537 synchronized(mWindowMap) {
4538 if (mDisplayEnabled) {
4539 return;
4540 }
4541 if (!mSystemBooted) {
4542 return;
4543 }
Romain Guy06882f82009-06-10 13:36:04 -07004544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 // Don't enable the screen until all existing windows
4546 // have been drawn.
4547 final int N = mWindows.size();
4548 for (int i=0; i<N; i++) {
4549 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn5943c202010-04-12 21:36:49 -07004550 if (w.isVisibleLw() && !w.mObscured
4551 && (w.mOrientationChanging || !w.isDrawnLw())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 return;
4553 }
4554 }
Romain Guy06882f82009-06-10 13:36:04 -07004555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004556 mDisplayEnabled = true;
4557 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004558 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 StringWriter sw = new StringWriter();
4560 PrintWriter pw = new PrintWriter(sw);
4561 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004562 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 }
4564 try {
4565 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4566 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004567 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 Parcel data = Parcel.obtain();
4569 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4570 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4571 data, null, 0);
4572 data.recycle();
4573 }
4574 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004575 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 }
4577 }
Romain Guy06882f82009-06-10 13:36:04 -07004578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004582 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4583 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 }
Romain Guy06882f82009-06-10 13:36:04 -07004585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 public void setInTouchMode(boolean mode) {
4587 synchronized(mWindowMap) {
4588 mInTouchMode = mode;
4589 }
4590 }
4591
Romain Guy06882f82009-06-10 13:36:04 -07004592 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004593 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004594 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004595 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004596 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 }
4598
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004599 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
Romain Guy06882f82009-06-10 13:36:04 -07004601
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004602 public void setRotationUnchecked(int rotation,
4603 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004604 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 long origId = Binder.clearCallingIdentity();
4608 boolean changed;
4609 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004610 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 }
Romain Guy06882f82009-06-10 13:36:04 -07004612
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004613 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 sendNewConfiguration();
4615 }
Romain Guy06882f82009-06-10 13:36:04 -07004616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 Binder.restoreCallingIdentity(origId);
4618 }
Romain Guy06882f82009-06-10 13:36:04 -07004619
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004620 /**
4621 * Apply a new rotation to the screen, respecting the requests of
4622 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4623 * re-evaluate the desired rotation.
4624 *
4625 * Returns null if the rotation has been changed. In this case YOU
4626 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4627 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004628 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 boolean changed;
4630 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4631 rotation = mRequestedRotation;
4632 } else {
4633 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004634 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004636 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004637 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004639 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004643 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004644 "Rotation changed to " + rotation
4645 + " from " + mRotation
4646 + " (forceApp=" + mForcedAppOrientation
4647 + ", req=" + mRequestedRotation + ")");
4648 mRotation = rotation;
4649 mWindowsFreezingScreen = true;
4650 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4651 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4652 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004653 mWaitingForConfig = true;
4654 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004656 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004657 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4658 mInputManager.setDisplayOrientation(0, rotation);
4659 } else {
4660 mQueue.setOrientation(rotation);
4661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004663 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 }
4665 for (int i=mWindows.size()-1; i>=0; i--) {
4666 WindowState w = (WindowState)mWindows.get(i);
4667 if (w.mSurface != null) {
4668 w.mOrientationChanging = true;
4669 }
4670 }
4671 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4672 try {
4673 mRotationWatchers.get(i).onRotationChanged(rotation);
4674 } catch (RemoteException e) {
4675 }
4676 }
4677 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 return changed;
4680 }
Romain Guy06882f82009-06-10 13:36:04 -07004681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 public int getRotation() {
4683 return mRotation;
4684 }
4685
4686 public int watchRotation(IRotationWatcher watcher) {
4687 final IBinder watcherBinder = watcher.asBinder();
4688 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4689 public void binderDied() {
4690 synchronized (mWindowMap) {
4691 for (int i=0; i<mRotationWatchers.size(); i++) {
4692 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004693 IRotationWatcher removed = mRotationWatchers.remove(i);
4694 if (removed != null) {
4695 removed.asBinder().unlinkToDeath(this, 0);
4696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 i--;
4698 }
4699 }
4700 }
4701 }
4702 };
Romain Guy06882f82009-06-10 13:36:04 -07004703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 synchronized (mWindowMap) {
4705 try {
4706 watcher.asBinder().linkToDeath(dr, 0);
4707 mRotationWatchers.add(watcher);
4708 } catch (RemoteException e) {
4709 // Client died, no cleanup needed.
4710 }
Romain Guy06882f82009-06-10 13:36:04 -07004711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 return mRotation;
4713 }
4714 }
4715
4716 /**
4717 * Starts the view server on the specified port.
4718 *
4719 * @param port The port to listener to.
4720 *
4721 * @return True if the server was successfully started, false otherwise.
4722 *
4723 * @see com.android.server.ViewServer
4724 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4725 */
4726 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004727 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 return false;
4729 }
4730
4731 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4732 return false;
4733 }
4734
4735 if (port < 1024) {
4736 return false;
4737 }
4738
4739 if (mViewServer != null) {
4740 if (!mViewServer.isRunning()) {
4741 try {
4742 return mViewServer.start();
4743 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004744 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 }
4746 }
4747 return false;
4748 }
4749
4750 try {
4751 mViewServer = new ViewServer(this, port);
4752 return mViewServer.start();
4753 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004754 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 }
4756 return false;
4757 }
4758
Romain Guy06882f82009-06-10 13:36:04 -07004759 private boolean isSystemSecure() {
4760 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4761 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4762 }
4763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 /**
4765 * Stops the view server if it exists.
4766 *
4767 * @return True if the server stopped, false if it wasn't started or
4768 * couldn't be stopped.
4769 *
4770 * @see com.android.server.ViewServer
4771 */
4772 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004773 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 return false;
4775 }
4776
4777 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4778 return false;
4779 }
4780
4781 if (mViewServer != null) {
4782 return mViewServer.stop();
4783 }
4784 return false;
4785 }
4786
4787 /**
4788 * Indicates whether the view server is running.
4789 *
4790 * @return True if the server is running, false otherwise.
4791 *
4792 * @see com.android.server.ViewServer
4793 */
4794 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004795 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 return false;
4797 }
4798
4799 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4800 return false;
4801 }
4802
4803 return mViewServer != null && mViewServer.isRunning();
4804 }
4805
4806 /**
4807 * Lists all availble windows in the system. The listing is written in the
4808 * specified Socket's output stream with the following syntax:
4809 * windowHashCodeInHexadecimal windowName
4810 * Each line of the ouput represents a different window.
4811 *
4812 * @param client The remote client to send the listing to.
4813 * @return False if an error occured, true otherwise.
4814 */
4815 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004816 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004817 return false;
4818 }
4819
4820 boolean result = true;
4821
4822 Object[] windows;
4823 synchronized (mWindowMap) {
4824 windows = new Object[mWindows.size()];
4825 //noinspection unchecked
4826 windows = mWindows.toArray(windows);
4827 }
4828
4829 BufferedWriter out = null;
4830
4831 // Any uncaught exception will crash the system process
4832 try {
4833 OutputStream clientStream = client.getOutputStream();
4834 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4835
4836 final int count = windows.length;
4837 for (int i = 0; i < count; i++) {
4838 final WindowState w = (WindowState) windows[i];
4839 out.write(Integer.toHexString(System.identityHashCode(w)));
4840 out.write(' ');
4841 out.append(w.mAttrs.getTitle());
4842 out.write('\n');
4843 }
4844
4845 out.write("DONE.\n");
4846 out.flush();
4847 } catch (Exception e) {
4848 result = false;
4849 } finally {
4850 if (out != null) {
4851 try {
4852 out.close();
4853 } catch (IOException e) {
4854 result = false;
4855 }
4856 }
4857 }
4858
4859 return result;
4860 }
4861
4862 /**
4863 * Sends a command to a target window. The result of the command, if any, will be
4864 * written in the output stream of the specified socket.
4865 *
4866 * The parameters must follow this syntax:
4867 * windowHashcode extra
4868 *
4869 * Where XX is the length in characeters of the windowTitle.
4870 *
4871 * The first parameter is the target window. The window with the specified hashcode
4872 * will be the target. If no target can be found, nothing happens. The extra parameters
4873 * will be delivered to the target window and as parameters to the command itself.
4874 *
4875 * @param client The remote client to sent the result, if any, to.
4876 * @param command The command to execute.
4877 * @param parameters The command parameters.
4878 *
4879 * @return True if the command was successfully delivered, false otherwise. This does
4880 * not indicate whether the command itself was successful.
4881 */
4882 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004883 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004884 return false;
4885 }
4886
4887 boolean success = true;
4888 Parcel data = null;
4889 Parcel reply = null;
4890
4891 // Any uncaught exception will crash the system process
4892 try {
4893 // Find the hashcode of the window
4894 int index = parameters.indexOf(' ');
4895 if (index == -1) {
4896 index = parameters.length();
4897 }
4898 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004899 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900
4901 // Extract the command's parameter after the window description
4902 if (index < parameters.length()) {
4903 parameters = parameters.substring(index + 1);
4904 } else {
4905 parameters = "";
4906 }
4907
4908 final WindowManagerService.WindowState window = findWindow(hashCode);
4909 if (window == null) {
4910 return false;
4911 }
4912
4913 data = Parcel.obtain();
4914 data.writeInterfaceToken("android.view.IWindow");
4915 data.writeString(command);
4916 data.writeString(parameters);
4917 data.writeInt(1);
4918 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4919
4920 reply = Parcel.obtain();
4921
4922 final IBinder binder = window.mClient.asBinder();
4923 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4924 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4925
4926 reply.readException();
4927
4928 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004929 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930 success = false;
4931 } finally {
4932 if (data != null) {
4933 data.recycle();
4934 }
4935 if (reply != null) {
4936 reply.recycle();
4937 }
4938 }
4939
4940 return success;
4941 }
4942
4943 private WindowState findWindow(int hashCode) {
4944 if (hashCode == -1) {
4945 return getFocusedWindow();
4946 }
4947
4948 synchronized (mWindowMap) {
4949 final ArrayList windows = mWindows;
4950 final int count = windows.size();
4951
4952 for (int i = 0; i < count; i++) {
4953 WindowState w = (WindowState) windows.get(i);
4954 if (System.identityHashCode(w) == hashCode) {
4955 return w;
4956 }
4957 }
4958 }
4959
4960 return null;
4961 }
4962
4963 /*
4964 * Instruct the Activity Manager to fetch the current configuration and broadcast
4965 * that to config-changed listeners if appropriate.
4966 */
4967 void sendNewConfiguration() {
4968 try {
4969 mActivityManager.updateConfiguration(null);
4970 } catch (RemoteException e) {
4971 }
4972 }
Romain Guy06882f82009-06-10 13:36:04 -07004973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004974 public Configuration computeNewConfiguration() {
4975 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07004976 return computeNewConfigurationLocked();
4977 }
4978 }
Romain Guy06882f82009-06-10 13:36:04 -07004979
Dianne Hackbornc485a602009-03-24 22:39:49 -07004980 Configuration computeNewConfigurationLocked() {
4981 Configuration config = new Configuration();
4982 if (!computeNewConfigurationLocked(config)) {
4983 return null;
4984 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07004985 return config;
4986 }
Romain Guy06882f82009-06-10 13:36:04 -07004987
Dianne Hackbornc485a602009-03-24 22:39:49 -07004988 boolean computeNewConfigurationLocked(Configuration config) {
4989 if (mDisplay == null) {
4990 return false;
4991 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004992 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4993 mInputManager.getInputConfiguration(config);
4994 } else {
4995 mQueue.getInputConfiguration(config);
4996 }
Christopher Tateb696aee2010-04-02 19:08:30 -07004997
4998 // Use the effective "visual" dimensions based on current rotation
4999 final boolean rotated = (mRotation == Surface.ROTATION_90
5000 || mRotation == Surface.ROTATION_270);
5001 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5002 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5003
Dianne Hackbornc485a602009-03-24 22:39:49 -07005004 int orientation = Configuration.ORIENTATION_SQUARE;
5005 if (dw < dh) {
5006 orientation = Configuration.ORIENTATION_PORTRAIT;
5007 } else if (dw > dh) {
5008 orientation = Configuration.ORIENTATION_LANDSCAPE;
5009 }
5010 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005011
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005012 DisplayMetrics dm = new DisplayMetrics();
5013 mDisplay.getMetrics(dm);
5014 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5015
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005016 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005017 // Note we only do this once because at this point we don't
5018 // expect the screen to change in this way at runtime, and want
5019 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005020 int longSize = dw;
5021 int shortSize = dh;
5022 if (longSize < shortSize) {
5023 int tmp = longSize;
5024 longSize = shortSize;
5025 shortSize = tmp;
5026 }
5027 longSize = (int)(longSize/dm.density);
5028 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005029
Dianne Hackborn723738c2009-06-25 19:48:04 -07005030 // These semi-magic numbers define our compatibility modes for
5031 // applications with different screens. Don't change unless you
5032 // make sure to test lots and lots of apps!
5033 if (longSize < 470) {
5034 // This is shorter than an HVGA normal density screen (which
5035 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005036 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5037 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005038 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005039 // What size is this screen screen?
5040 if (longSize >= 800 && shortSize >= 600) {
5041 // SVGA or larger screens at medium density are the point
5042 // at which we consider it to be an extra large screen.
5043 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5044 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005045 // VGA or larger screens at medium density are the point
5046 // at which we consider it to be a large screen.
5047 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5048 } else {
5049 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005050
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005051 // If this screen is wider than normal HVGA, or taller
5052 // than FWVGA, then for old apps we want to run in size
5053 // compatibility mode.
5054 if (shortSize > 321 || longSize > 570) {
5055 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5056 }
5057 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005058
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005059 // Is this a long screen?
5060 if (((longSize*3)/5) >= (shortSize-1)) {
5061 // Anything wider than WVGA (5:3) is considering to be long.
5062 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5063 } else {
5064 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5065 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005066 }
5067 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005068 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005069
Dianne Hackbornc485a602009-03-24 22:39:49 -07005070 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5071 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5072 mPolicy.adjustConfigurationLw(config);
5073 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005074 }
Romain Guy06882f82009-06-10 13:36:04 -07005075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 // -------------------------------------------------------------
5077 // Input Events and Focus Management
5078 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005079
5080 public void getKeyEventTargets(InputTargetList inputTargets,
5081 KeyEvent event, int nature, int policyFlags) {
5082 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
5083
5084 // TODO what do we do with mDisplayFrozen?
5085 // TODO what do we do with focus.mToken.paused?
5086
5087 WindowState focus = getFocusedWindow();
5088 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
5089
5090 addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
5091 }
5092
5093 // Target of Motion events
5094 WindowState mTouchFocus;
5095
5096 // Windows above the target who would like to receive an "outside"
5097 // touch event for any down events outside of them.
5098 // (This is a linked list by way of WindowState.mNextOutsideTouch.)
5099 WindowState mOutsideTouchTargets;
5100
5101 private void clearTouchFocus() {
5102 mTouchFocus = null;
5103 mOutsideTouchTargets = null;
5104 }
5105
5106 public void getMotionEventTargets(InputTargetList inputTargets,
5107 MotionEvent event, int nature, int policyFlags) {
5108 if (nature == InputQueue.INPUT_EVENT_NATURE_TRACKBALL) {
5109 // More or less the same as for keys...
5110 WindowState focus = getFocusedWindow();
5111 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
5112
5113 addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
5114 return;
5115 }
5116
5117 int action = event.getAction();
5118
5119 // TODO detect cheek presses somewhere... either here or in native code
5120
5121 final boolean screenWasOff = (policyFlags & WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
5122
5123 WindowState target = mTouchFocus;
5124
5125 if (action == MotionEvent.ACTION_UP) {
5126 // let go of our target
5127 mPowerManager.logPointerUpEvent();
5128 clearTouchFocus();
5129 } else if (action == MotionEvent.ACTION_DOWN) {
5130 // acquire a new target
5131 mPowerManager.logPointerDownEvent();
5132
5133 synchronized (mWindowMap) {
5134 if (mTouchFocus != null) {
5135 // this is weird, we got a pen down, but we thought it was
5136 // already down!
5137 // XXX: We should probably send an ACTION_UP to the current
5138 // target.
5139 Slog.w(TAG, "Pointer down received while already down in: "
5140 + mTouchFocus);
5141 clearTouchFocus();
5142 }
5143
5144 // ACTION_DOWN is special, because we need to lock next events to
5145 // the window we'll land onto.
5146 final int x = (int) event.getX();
5147 final int y = (int) event.getY();
5148
5149 final ArrayList windows = mWindows;
5150 final int N = windows.size();
5151 WindowState topErrWindow = null;
5152 final Rect tmpRect = mTempRect;
5153 for (int i=N-1; i>=0; i--) {
5154 WindowState child = (WindowState)windows.get(i);
5155 //Slog.i(TAG, "Checking dispatch to: " + child);
5156 final int flags = child.mAttrs.flags;
5157 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
5158 if (topErrWindow == null) {
5159 topErrWindow = child;
5160 }
5161 }
5162 if (!child.isVisibleLw()) {
5163 //Slog.i(TAG, "Not visible!");
5164 continue;
5165 }
5166 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
5167 //Slog.i(TAG, "Not touchable!");
5168 if ((flags & WindowManager.LayoutParams
5169 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
5170 child.mNextOutsideTouch = mOutsideTouchTargets;
5171 mOutsideTouchTargets = child;
5172 }
5173 continue;
5174 }
5175 tmpRect.set(child.mFrame);
5176 if (child.mTouchableInsets == ViewTreeObserver
5177 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
5178 // The touch is inside of the window if it is
5179 // inside the frame, AND the content part of that
5180 // frame that was given by the application.
5181 tmpRect.left += child.mGivenContentInsets.left;
5182 tmpRect.top += child.mGivenContentInsets.top;
5183 tmpRect.right -= child.mGivenContentInsets.right;
5184 tmpRect.bottom -= child.mGivenContentInsets.bottom;
5185 } else if (child.mTouchableInsets == ViewTreeObserver
5186 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
5187 // The touch is inside of the window if it is
5188 // inside the frame, AND the visible part of that
5189 // frame that was given by the application.
5190 tmpRect.left += child.mGivenVisibleInsets.left;
5191 tmpRect.top += child.mGivenVisibleInsets.top;
5192 tmpRect.right -= child.mGivenVisibleInsets.right;
5193 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
5194 }
5195 final int touchFlags = flags &
5196 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5197 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
5198 if (tmpRect.contains(x, y) || touchFlags == 0) {
5199 //Slog.i(TAG, "Using this target!");
5200 if (!screenWasOff || (flags &
5201 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
5202 mTouchFocus = child;
5203 } else {
5204 //Slog.i(TAG, "Waking, skip!");
5205 mTouchFocus = null;
5206 }
5207 break;
5208 }
5209
5210 if ((flags & WindowManager.LayoutParams
5211 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
5212 child.mNextOutsideTouch = mOutsideTouchTargets;
5213 mOutsideTouchTargets = child;
5214 //Slog.i(TAG, "Adding to outside target list: " + child);
5215 }
5216 }
5217
5218 // if there's an error window but it's not accepting
5219 // focus (typically because it is not yet visible) just
5220 // wait for it -- any other focused window may in fact
5221 // be in ANR state.
5222 if (topErrWindow != null && mTouchFocus != topErrWindow) {
5223 mTouchFocus = null;
5224 }
5225 }
5226
5227 target = mTouchFocus;
5228 }
5229
5230 if (target != null) {
5231 wakeupIfNeeded(target, eventType(event));
5232 }
5233
5234 int targetFlags = 0;
5235 if (target == null) {
5236 // In this case we are either dropping the event, or have received
5237 // a move or up without a down. It is common to receive move
5238 // events in such a way, since this means the user is moving the
5239 // pointer without actually pressing down. All other cases should
5240 // be atypical, so let's log them.
5241 if (action != MotionEvent.ACTION_MOVE) {
5242 Slog.w(TAG, "No window to dispatch pointer action " + action);
5243 }
5244 } else {
5245 if ((target.mAttrs.flags &
5246 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5247 //target wants to ignore fat touch events
5248 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(event);
5249 //explicit flag to return without processing event further
5250 boolean returnFlag = false;
5251 if((action == MotionEvent.ACTION_DOWN)) {
5252 mFatTouch = false;
5253 if(cheekPress) {
5254 mFatTouch = true;
5255 returnFlag = true;
5256 }
5257 } else {
5258 if(action == MotionEvent.ACTION_UP) {
5259 if(mFatTouch) {
5260 //earlier even was invalid doesnt matter if current up is cheekpress or not
5261 mFatTouch = false;
5262 returnFlag = true;
5263 } else if(cheekPress) {
5264 //cancel the earlier event
5265 targetFlags |= InputTarget.FLAG_CANCEL;
5266 action = MotionEvent.ACTION_CANCEL;
5267 }
5268 } else if(action == MotionEvent.ACTION_MOVE) {
5269 if(mFatTouch) {
5270 //two cases here
5271 //an invalid down followed by 0 or moves(valid or invalid)
5272 //a valid down, invalid move, more moves. want to ignore till up
5273 returnFlag = true;
5274 } else if(cheekPress) {
5275 //valid down followed by invalid moves
5276 //an invalid move have to cancel earlier action
5277 targetFlags |= InputTarget.FLAG_CANCEL;
5278 action = MotionEvent.ACTION_CANCEL;
5279 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
5280 //note that the subsequent invalid moves will not get here
5281 mFatTouch = true;
5282 }
5283 }
5284 } //else if action
5285 if(returnFlag) {
5286 return;
5287 }
5288 } //end if target
5289 }
5290
5291 synchronized (mWindowMap) {
5292 if (target != null && ! target.isVisibleLw()) {
5293 target = null;
5294 }
5295
5296 if (action == MotionEvent.ACTION_DOWN) {
5297 while (mOutsideTouchTargets != null) {
5298 addInputTarget(inputTargets, mOutsideTouchTargets,
5299 InputTarget.FLAG_OUTSIDE | targetFlags);
5300 mOutsideTouchTargets = mOutsideTouchTargets.mNextOutsideTouch;
5301 }
5302 }
5303
5304 // If we sent an initial down to the wallpaper, then continue
5305 // sending events until the final up.
5306 // Alternately if we are on top of the wallpaper, then the wallpaper also
5307 // gets to see this movement.
5308 if (mSendingPointersToWallpaper ||
5309 (target != null && action == MotionEvent.ACTION_DOWN
5310 && mWallpaperTarget == target
5311 && target.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)) {
5312 int curTokenIndex = mWallpaperTokens.size();
5313 while (curTokenIndex > 0) {
5314 curTokenIndex--;
5315 WindowToken token = mWallpaperTokens.get(curTokenIndex);
5316 int curWallpaperIndex = token.windows.size();
5317 while (curWallpaperIndex > 0) {
5318 curWallpaperIndex--;
5319 WindowState wallpaper = token.windows.get(curWallpaperIndex);
5320 if ((wallpaper.mAttrs.flags &
5321 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
5322 continue;
5323 }
5324
5325 switch (action) {
5326 case MotionEvent.ACTION_DOWN:
5327 mSendingPointersToWallpaper = true;
5328 break;
5329 case MotionEvent.ACTION_UP:
5330 mSendingPointersToWallpaper = false;
5331 break;
5332 }
5333
5334 addInputTarget(inputTargets, wallpaper, targetFlags);
5335 }
5336 }
5337 }
5338
5339 if (target != null) {
5340 addInputTarget(inputTargets, target, InputTarget.FLAG_SYNC | targetFlags);
5341 }
5342 }
5343 }
5344
5345 private void addInputTarget(InputTargetList inputTargets, WindowState window, int flags) {
5346 if (window.mInputChannel == null) {
5347 return;
5348 }
5349
5350 long timeoutNanos = -1;
5351 IApplicationToken appToken = window.getAppToken();
5352
5353 if (appToken != null) {
5354 try {
5355 timeoutNanos = appToken.getKeyDispatchingTimeout() * 1000000;
5356 } catch (RemoteException ex) {
5357 Slog.w(TAG, "Could not get key dispatching timeout.", ex);
5358 }
5359 }
5360
5361 inputTargets.add(window.mInputChannel, flags, timeoutNanos,
5362 - window.mFrame.left, - window.mFrame.top);
5363 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364
5365 private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
Michael Chane96440f2009-05-06 10:27:36 -07005366 long curTime = SystemClock.uptimeMillis();
5367
Michael Chane10de972009-05-18 11:24:50 -07005368 if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
Michael Chane96440f2009-05-06 10:27:36 -07005369 if (mLastTouchEventType == eventType &&
5370 (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
5371 return;
5372 }
5373 mLastUserActivityCallTime = curTime;
5374 mLastTouchEventType = eventType;
5375 }
5376
5377 if (targetWin == null
5378 || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
5379 mPowerManager.userActivity(curTime, false, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005380 }
5381 }
5382
5383 // tells if it's a cheek event or not -- this function is stateful
5384 private static final int EVENT_NONE = 0;
5385 private static final int EVENT_UNKNOWN = 0;
5386 private static final int EVENT_CHEEK = 0;
5387 private static final int EVENT_IGNORE_DURATION = 300; // ms
5388 private static final float CHEEK_THRESHOLD = 0.6f;
5389 private int mEventState = EVENT_NONE;
5390 private float mEventSize;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005392 private int eventType(MotionEvent ev) {
5393 float size = ev.getSize();
5394 switch (ev.getAction()) {
5395 case MotionEvent.ACTION_DOWN:
5396 mEventSize = size;
5397 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
5398 case MotionEvent.ACTION_UP:
5399 if (size > mEventSize) mEventSize = size;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005400 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 case MotionEvent.ACTION_MOVE:
5402 final int N = ev.getHistorySize();
5403 if (size > mEventSize) mEventSize = size;
5404 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5405 for (int i=0; i<N; i++) {
5406 size = ev.getHistoricalSize(i);
5407 if (size > mEventSize) mEventSize = size;
5408 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5409 }
5410 if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
5411 return TOUCH_EVENT;
5412 } else {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005413 return LONG_TOUCH_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005414 }
5415 default:
5416 // not good
5417 return OTHER_EVENT;
5418 }
5419 }
5420
5421 /**
5422 * @return Returns true if event was dispatched, false if it was dropped for any reason
5423 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005424 private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005425 if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426 "dispatchPointer " + ev);
5427
Michael Chan53071d62009-05-13 17:29:48 -07005428 if (MEASURE_LATENCY) {
5429 lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
5430 }
5431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005433 ev, true, false, pid, uid);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005434
Michael Chan53071d62009-05-13 17:29:48 -07005435 if (MEASURE_LATENCY) {
5436 lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
5437 }
5438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 int action = ev.getAction();
Romain Guy06882f82009-06-10 13:36:04 -07005440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 if (action == MotionEvent.ACTION_UP) {
5442 // let go of our target
5443 mKeyWaiter.mMotionTarget = null;
5444 mPowerManager.logPointerUpEvent();
5445 } else if (action == MotionEvent.ACTION_DOWN) {
5446 mPowerManager.logPointerDownEvent();
5447 }
5448
5449 if (targetObj == null) {
5450 // In this case we are either dropping the event, or have received
5451 // a move or up without a down. It is common to receive move
5452 // events in such a way, since this means the user is moving the
5453 // pointer without actually pressing down. All other cases should
5454 // be atypical, so let's log them.
Michael Chane96440f2009-05-06 10:27:36 -07005455 if (action != MotionEvent.ACTION_MOVE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005456 Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 }
Dianne Hackborn6adba242009-11-10 11:10:09 -08005458 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005459 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005461 if (qev != null) {
5462 mQueue.recycleEvent(qev);
5463 }
5464 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005465 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 }
5467 if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005468 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005469 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005471 if (qev != null) {
5472 mQueue.recycleEvent(qev);
5473 }
5474 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005475 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 }
Romain Guy06882f82009-06-10 13:36:04 -07005477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005478 WindowState target = (WindowState)targetObj;
Romain Guy06882f82009-06-10 13:36:04 -07005479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005480 final long eventTime = ev.getEventTime();
Michael Chan53071d62009-05-13 17:29:48 -07005481 final long eventTimeNano = ev.getEventTimeNano();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005482
Joe Onorato8a9b2202010-02-26 18:56:32 -08005483 //Slog.i(TAG, "Sending " + ev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484
5485 if (uid != 0 && uid != target.mSession.mUid) {
5486 if (mContext.checkPermission(
5487 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5488 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005489 Slog.w(TAG, "Permission denied: injecting pointer event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 + pid + " uid " + uid + " to window " + target
5491 + " owned by uid " + target.mSession.mUid);
5492 if (qev != null) {
5493 mQueue.recycleEvent(qev);
5494 }
5495 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005496 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005497 }
5498 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005499
Michael Chan53071d62009-05-13 17:29:48 -07005500 if (MEASURE_LATENCY) {
5501 lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5502 }
5503
Romain Guy06882f82009-06-10 13:36:04 -07005504 if ((target.mAttrs.flags &
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5506 //target wants to ignore fat touch events
5507 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
5508 //explicit flag to return without processing event further
5509 boolean returnFlag = false;
5510 if((action == MotionEvent.ACTION_DOWN)) {
5511 mFatTouch = false;
5512 if(cheekPress) {
5513 mFatTouch = true;
5514 returnFlag = true;
5515 }
5516 } else {
5517 if(action == MotionEvent.ACTION_UP) {
5518 if(mFatTouch) {
5519 //earlier even was invalid doesnt matter if current up is cheekpress or not
5520 mFatTouch = false;
5521 returnFlag = true;
5522 } else if(cheekPress) {
5523 //cancel the earlier event
5524 ev.setAction(MotionEvent.ACTION_CANCEL);
5525 action = MotionEvent.ACTION_CANCEL;
5526 }
5527 } else if(action == MotionEvent.ACTION_MOVE) {
5528 if(mFatTouch) {
5529 //two cases here
5530 //an invalid down followed by 0 or moves(valid or invalid)
Romain Guy06882f82009-06-10 13:36:04 -07005531 //a valid down, invalid move, more moves. want to ignore till up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005532 returnFlag = true;
5533 } else if(cheekPress) {
5534 //valid down followed by invalid moves
5535 //an invalid move have to cancel earlier action
5536 ev.setAction(MotionEvent.ACTION_CANCEL);
5537 action = MotionEvent.ACTION_CANCEL;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005538 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 //note that the subsequent invalid moves will not get here
5540 mFatTouch = true;
5541 }
5542 }
5543 } //else if action
5544 if(returnFlag) {
5545 //recycle que, ev
5546 if (qev != null) {
5547 mQueue.recycleEvent(qev);
5548 }
5549 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005550 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 }
5552 } //end if target
Michael Chane96440f2009-05-06 10:27:36 -07005553
Michael Chan9f028e62009-08-04 17:37:46 -07005554 // Enable this for testing the "right" value
5555 if (false && action == MotionEvent.ACTION_DOWN) {
Michael Chane96440f2009-05-06 10:27:36 -07005556 int max_events_per_sec = 35;
5557 try {
5558 max_events_per_sec = Integer.parseInt(SystemProperties
5559 .get("windowsmgr.max_events_per_sec"));
5560 if (max_events_per_sec < 1) {
5561 max_events_per_sec = 35;
5562 }
5563 } catch (NumberFormatException e) {
5564 }
5565 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
5566 }
5567
5568 /*
5569 * Throttle events to minimize CPU usage when there's a flood of events
5570 * e.g. constant contact with the screen
5571 */
5572 if (action == MotionEvent.ACTION_MOVE) {
5573 long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
5574 long now = SystemClock.uptimeMillis();
5575 if (now < nextEventTime) {
5576 try {
5577 Thread.sleep(nextEventTime - now);
5578 } catch (InterruptedException e) {
5579 }
5580 mLastTouchEventTime = nextEventTime;
5581 } else {
5582 mLastTouchEventTime = now;
5583 }
5584 }
5585
Michael Chan53071d62009-05-13 17:29:48 -07005586 if (MEASURE_LATENCY) {
5587 lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5588 }
5589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 synchronized(mWindowMap) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005591 if (!target.isVisibleLw()) {
5592 // During this motion dispatch, the target window has become
5593 // invisible.
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005594 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005595 if (qev != null) {
5596 mQueue.recycleEvent(qev);
5597 }
5598 ev.recycle();
5599 return INJECT_SUCCEEDED;
5600 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005602 if (qev != null && action == MotionEvent.ACTION_MOVE) {
5603 mKeyWaiter.bindTargetWindowLocked(target,
5604 KeyWaiter.RETURN_PENDING_POINTER, qev);
5605 ev = null;
5606 } else {
5607 if (action == MotionEvent.ACTION_DOWN) {
5608 WindowState out = mKeyWaiter.mOutsideTouchTargets;
5609 if (out != null) {
5610 MotionEvent oev = MotionEvent.obtain(ev);
5611 oev.setAction(MotionEvent.ACTION_OUTSIDE);
5612 do {
5613 final Rect frame = out.mFrame;
5614 oev.offsetLocation(-(float)frame.left, -(float)frame.top);
5615 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005616 out.mClient.dispatchPointer(oev, eventTime, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005618 Slog.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005619 }
5620 oev.offsetLocation((float)frame.left, (float)frame.top);
5621 out = out.mNextOutsideTouch;
5622 } while (out != null);
5623 mKeyWaiter.mOutsideTouchTargets = null;
5624 }
5625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005626
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005627 dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005628
Dianne Hackborn6adba242009-11-10 11:10:09 -08005629 final Rect frame = target.mFrame;
5630 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
5631 mKeyWaiter.bindTargetWindowLocked(target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005632 }
5633 }
Romain Guy06882f82009-06-10 13:36:04 -07005634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005635 // finally offset the event to the target's coordinate system and
5636 // dispatch the event.
5637 try {
5638 if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005639 Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005640 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005641
Michael Chan53071d62009-05-13 17:29:48 -07005642 if (MEASURE_LATENCY) {
5643 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
5644 }
5645
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005646 target.mClient.dispatchPointer(ev, eventTime, true);
Michael Chan53071d62009-05-13 17:29:48 -07005647
5648 if (MEASURE_LATENCY) {
5649 lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
5650 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005651 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005652 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005653 Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005654 mKeyWaiter.mMotionTarget = null;
5655 try {
5656 removeWindow(target.mSession, target.mClient);
5657 } catch (java.util.NoSuchElementException ex) {
5658 // This will happen if the window has already been
5659 // removed.
5660 }
5661 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005662 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005663 }
Romain Guy06882f82009-06-10 13:36:04 -07005664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 /**
5666 * @return Returns true if event was dispatched, false if it was dropped for any reason
5667 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005668 private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005669 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
Romain Guy06882f82009-06-10 13:36:04 -07005671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005673 ev, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005675 Slog.w(TAG, "No focus window, dropping trackball: " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 if (qev != null) {
5677 mQueue.recycleEvent(qev);
5678 }
5679 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005680 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 }
5682 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
5683 if (qev != null) {
5684 mQueue.recycleEvent(qev);
5685 }
5686 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005687 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
Romain Guy06882f82009-06-10 13:36:04 -07005689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 if (uid != 0 && uid != focus.mSession.mUid) {
5693 if (mContext.checkPermission(
5694 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5695 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005696 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 + pid + " uid " + uid + " to window " + focus
5698 + " owned by uid " + focus.mSession.mUid);
5699 if (qev != null) {
5700 mQueue.recycleEvent(qev);
5701 }
5702 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005703 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 }
5705 }
Romain Guy06882f82009-06-10 13:36:04 -07005706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005707 final long eventTime = ev.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709 synchronized(mWindowMap) {
5710 if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
5711 mKeyWaiter.bindTargetWindowLocked(focus,
5712 KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
5713 // We don't deliver movement events to the client, we hold
5714 // them and wait for them to call back.
5715 ev = null;
5716 } else {
5717 mKeyWaiter.bindTargetWindowLocked(focus);
5718 }
5719 }
Romain Guy06882f82009-06-10 13:36:04 -07005720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005722 focus.mClient.dispatchTrackball(ev, eventTime, true);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005723 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005725 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 try {
5727 removeWindow(focus.mSession, focus.mClient);
5728 } catch (java.util.NoSuchElementException ex) {
5729 // This will happen if the window has already been
5730 // removed.
5731 }
5732 }
Romain Guy06882f82009-06-10 13:36:04 -07005733
Dianne Hackborncfaef692009-06-15 14:24:44 -07005734 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005735 }
Romain Guy06882f82009-06-10 13:36:04 -07005736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005737 /**
5738 * @return Returns true if event was dispatched, false if it was dropped for any reason
5739 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005740 private int dispatchKey(KeyEvent event, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005741 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742
5743 Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005744 null, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005745 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005746 Slog.w(TAG, "No focus window, dropping: " + event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005747 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 }
5749 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005750 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 }
Romain Guy06882f82009-06-10 13:36:04 -07005752
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07005753 // Okay we have finished waiting for the last event to be processed.
5754 // First off, if this is a repeat event, check to see if there is
5755 // a corresponding up event in the queue. If there is, we will
5756 // just drop the repeat, because it makes no sense to repeat after
5757 // the user has released a key. (This is especially important for
5758 // long presses.)
5759 if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
5760 return INJECT_SUCCEEDED;
5761 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005764
Joe Onorato8a9b2202010-02-26 18:56:32 -08005765 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766 TAG, "Dispatching to " + focus + ": " + event);
5767
5768 if (uid != 0 && uid != focus.mSession.mUid) {
5769 if (mContext.checkPermission(
5770 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5771 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005772 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005773 + pid + " uid " + uid + " to window " + focus
5774 + " owned by uid " + focus.mSession.mUid);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005775 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 }
5777 }
Romain Guy06882f82009-06-10 13:36:04 -07005778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 synchronized(mWindowMap) {
5780 mKeyWaiter.bindTargetWindowLocked(focus);
5781 }
5782
5783 // NOSHIP extra state logging
5784 mKeyWaiter.recordDispatchState(event, focus);
5785 // END NOSHIP
Romain Guy06882f82009-06-10 13:36:04 -07005786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 try {
5788 if (DEBUG_INPUT || DEBUG_FOCUS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005789 Slog.v(TAG, "Delivering key " + event.getKeyCode()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 + " to " + focus);
5791 }
5792 focus.mClient.dispatchKey(event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005793 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005795 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005796 try {
5797 removeWindow(focus.mSession, focus.mClient);
5798 } catch (java.util.NoSuchElementException ex) {
5799 // This will happen if the window has already been
5800 // removed.
5801 }
5802 }
Romain Guy06882f82009-06-10 13:36:04 -07005803
Dianne Hackborncfaef692009-06-15 14:24:44 -07005804 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805 }
Romain Guy06882f82009-06-10 13:36:04 -07005806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 public void pauseKeyDispatching(IBinder _token) {
5808 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5809 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005810 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811 }
5812
5813 synchronized (mWindowMap) {
5814 WindowToken token = mTokenMap.get(_token);
5815 if (token != null) {
5816 mKeyWaiter.pauseDispatchingLocked(token);
5817 }
5818 }
5819 }
5820
5821 public void resumeKeyDispatching(IBinder _token) {
5822 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5823 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005824 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 }
5826
5827 synchronized (mWindowMap) {
5828 WindowToken token = mTokenMap.get(_token);
5829 if (token != null) {
5830 mKeyWaiter.resumeDispatchingLocked(token);
5831 }
5832 }
5833 }
5834
5835 public void setEventDispatching(boolean enabled) {
5836 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5837 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005838 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 }
5840
5841 synchronized (mWindowMap) {
5842 mKeyWaiter.setEventDispatchingLocked(enabled);
5843 }
5844 }
Romain Guy06882f82009-06-10 13:36:04 -07005845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005846 /**
5847 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005848 *
5849 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005850 * {@link SystemClock#uptimeMillis()} as the timebase.)
5851 * @param sync If true, wait for the event to be completed before returning to the caller.
5852 * @return Returns true if event was dispatched, false if it was dropped for any reason
5853 */
5854 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5855 long downTime = ev.getDownTime();
5856 long eventTime = ev.getEventTime();
5857
5858 int action = ev.getAction();
5859 int code = ev.getKeyCode();
5860 int repeatCount = ev.getRepeatCount();
5861 int metaState = ev.getMetaState();
5862 int deviceId = ev.getDeviceId();
5863 int scancode = ev.getScanCode();
5864
5865 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5866 if (downTime == 0) downTime = eventTime;
5867
5868 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07005869 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005870
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005871 final int pid = Binder.getCallingPid();
5872 final int uid = Binder.getCallingUid();
5873 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005874
5875 final int result;
5876 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5877 result = mInputManager.injectKeyEvent(newEvent,
5878 InputQueue.INPUT_EVENT_NATURE_KEY, sync, pid, uid);
5879 } else {
5880 result = dispatchKey(newEvent, pid, uid);
5881 if (sync) {
5882 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005885
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005886 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005887 switch (result) {
5888 case INJECT_NO_PERMISSION:
5889 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305890 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005891 case INJECT_SUCCEEDED:
5892 return true;
5893 }
5894 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005895 }
5896
5897 /**
5898 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005899 *
5900 * @param ev A motion event describing the pointer (touch) action. (As noted in
5901 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 * {@link SystemClock#uptimeMillis()} as the timebase.)
5903 * @param sync If true, wait for the event to be completed before returning to the caller.
5904 * @return Returns true if event was dispatched, false if it was dropped for any reason
5905 */
5906 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005907 final int pid = Binder.getCallingPid();
5908 final int uid = Binder.getCallingUid();
5909 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005910
5911 final int result;
5912 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5913 result = mInputManager.injectMotionEvent(ev,
5914 InputQueue.INPUT_EVENT_NATURE_TOUCH, sync, pid, uid);
5915 } else {
5916 result = dispatchPointer(null, ev, pid, uid);
5917 if (sync) {
5918 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005921
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005922 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005923 switch (result) {
5924 case INJECT_NO_PERMISSION:
5925 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305926 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005927 case INJECT_SUCCEEDED:
5928 return true;
5929 }
5930 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 }
Romain Guy06882f82009-06-10 13:36:04 -07005932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 /**
5934 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005935 *
5936 * @param ev A motion event describing the trackball action. (As noted in
5937 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 * {@link SystemClock#uptimeMillis()} as the timebase.)
5939 * @param sync If true, wait for the event to be completed before returning to the caller.
5940 * @return Returns true if event was dispatched, false if it was dropped for any reason
5941 */
5942 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005943 final int pid = Binder.getCallingPid();
5944 final int uid = Binder.getCallingUid();
5945 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005946
5947 final int result;
5948 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5949 result = mInputManager.injectMotionEvent(ev,
5950 InputQueue.INPUT_EVENT_NATURE_TRACKBALL, sync, pid, uid);
5951 } else {
5952 result = dispatchTrackball(null, ev, pid, uid);
5953 if (sync) {
5954 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
5955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005956 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005957
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005958 Binder.restoreCallingIdentity(ident);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005959 switch (result) {
5960 case INJECT_NO_PERMISSION:
5961 throw new SecurityException(
Chander S Pechetty27f3de62010-02-10 22:14:00 +05305962 "Injecting to another application requires INJECT_EVENTS permission");
Dianne Hackborncfaef692009-06-15 14:24:44 -07005963 case INJECT_SUCCEEDED:
5964 return true;
5965 }
5966 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005967 }
Romain Guy06882f82009-06-10 13:36:04 -07005968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 private WindowState getFocusedWindow() {
5970 synchronized (mWindowMap) {
5971 return getFocusedWindowLocked();
5972 }
5973 }
5974
5975 private WindowState getFocusedWindowLocked() {
5976 return mCurrentFocus;
5977 }
Romain Guy06882f82009-06-10 13:36:04 -07005978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 /**
5980 * This class holds the state for dispatching key events. This state
5981 * is protected by the KeyWaiter instance, NOT by the window lock. You
5982 * can be holding the main window lock while acquire the KeyWaiter lock,
5983 * but not the other way around.
5984 */
5985 final class KeyWaiter {
5986 // NOSHIP debugging
5987 public class DispatchState {
5988 private KeyEvent event;
5989 private WindowState focus;
5990 private long time;
5991 private WindowState lastWin;
5992 private IBinder lastBinder;
5993 private boolean finished;
5994 private boolean gotFirstWindow;
5995 private boolean eventDispatching;
5996 private long timeToSwitch;
5997 private boolean wasFrozen;
5998 private boolean focusPaused;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08005999 private WindowState curFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006001 DispatchState(KeyEvent theEvent, WindowState theFocus) {
6002 focus = theFocus;
6003 event = theEvent;
6004 time = System.currentTimeMillis();
6005 // snapshot KeyWaiter state
6006 lastWin = mLastWin;
6007 lastBinder = mLastBinder;
6008 finished = mFinished;
6009 gotFirstWindow = mGotFirstWindow;
6010 eventDispatching = mEventDispatching;
6011 timeToSwitch = mTimeToSwitch;
6012 wasFrozen = mWasFrozen;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006013 curFocus = mCurrentFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006014 // cache the paused state at ctor time as well
6015 if (theFocus == null || theFocus.mToken == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 focusPaused = false;
6017 } else {
6018 focusPaused = theFocus.mToken.paused;
6019 }
6020 }
Romain Guy06882f82009-06-10 13:36:04 -07006021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 public String toString() {
6023 return "{{" + event + " to " + focus + " @ " + time
6024 + " lw=" + lastWin + " lb=" + lastBinder
6025 + " fin=" + finished + " gfw=" + gotFirstWindow
6026 + " ed=" + eventDispatching + " tts=" + timeToSwitch
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006027 + " wf=" + wasFrozen + " fp=" + focusPaused
Christopher Tate46d45252010-02-09 15:48:57 -08006028 + " mcf=" + curFocus + "}}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006029 }
6030 };
6031 private DispatchState mDispatchState = null;
6032 public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
6033 mDispatchState = new DispatchState(theEvent, theFocus);
6034 }
6035 // END NOSHIP
6036
6037 public static final int RETURN_NOTHING = 0;
6038 public static final int RETURN_PENDING_POINTER = 1;
6039 public static final int RETURN_PENDING_TRACKBALL = 2;
Romain Guy06882f82009-06-10 13:36:04 -07006040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 final Object SKIP_TARGET_TOKEN = new Object();
6042 final Object CONSUMED_EVENT_TOKEN = new Object();
Romain Guy06882f82009-06-10 13:36:04 -07006043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006044 private WindowState mLastWin = null;
6045 private IBinder mLastBinder = null;
6046 private boolean mFinished = true;
6047 private boolean mGotFirstWindow = false;
6048 private boolean mEventDispatching = true;
6049 private long mTimeToSwitch = 0;
6050 /* package */ boolean mWasFrozen = false;
Romain Guy06882f82009-06-10 13:36:04 -07006051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 // Target of Motion events
6053 WindowState mMotionTarget;
Romain Guy06882f82009-06-10 13:36:04 -07006054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 // Windows above the target who would like to receive an "outside"
6056 // touch event for any down events outside of them.
6057 WindowState mOutsideTouchTargets;
6058
6059 /**
6060 * Wait for the last event dispatch to complete, then find the next
6061 * target that should receive the given event and wait for that one
6062 * to be ready to receive it.
6063 */
6064 Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
6065 MotionEvent nextMotion, boolean isPointerEvent,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006066 boolean failIfTimeout, int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006067 long startTime = SystemClock.uptimeMillis();
6068 long keyDispatchingTimeout = 5 * 1000;
6069 long waitedFor = 0;
6070
6071 while (true) {
6072 // Figure out which window we care about. It is either the
6073 // last window we are waiting to have process the event or,
6074 // if none, then the next window we think the event should go
6075 // to. Note: we retrieve mLastWin outside of the lock, so
6076 // it may change before we lock. Thus we must check it again.
6077 WindowState targetWin = mLastWin;
6078 boolean targetIsNew = targetWin == null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006079 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 TAG, "waitForLastKey: mFinished=" + mFinished +
6081 ", mLastWin=" + mLastWin);
6082 if (targetIsNew) {
6083 Object target = findTargetWindow(nextKey, qev, nextMotion,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006084 isPointerEvent, callingPid, callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 if (target == SKIP_TARGET_TOKEN) {
6086 // The user has pressed a special key, and we are
6087 // dropping all pending events before it.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006088 if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 + " " + nextMotion);
6090 return null;
6091 }
6092 if (target == CONSUMED_EVENT_TOKEN) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006093 if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 + " " + nextMotion);
6095 return target;
6096 }
6097 targetWin = (WindowState)target;
6098 }
Romain Guy06882f82009-06-10 13:36:04 -07006099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 AppWindowToken targetApp = null;
Romain Guy06882f82009-06-10 13:36:04 -07006101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 // Now: is it okay to send the next event to this window?
6103 synchronized (this) {
6104 // First: did we come here based on the last window not
6105 // being null, but it changed by the time we got here?
6106 // If so, try again.
6107 if (!targetIsNew && mLastWin == null) {
6108 continue;
6109 }
Romain Guy06882f82009-06-10 13:36:04 -07006110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 // We never dispatch events if not finished with the
6112 // last one, or the display is frozen.
6113 if (mFinished && !mDisplayFrozen) {
6114 // If event dispatching is disabled, then we
6115 // just consume the events.
6116 if (!mEventDispatching) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006117 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 "Skipping event; dispatching disabled: "
6119 + nextKey + " " + nextMotion);
6120 return null;
6121 }
6122 if (targetWin != null) {
6123 // If this is a new target, and that target is not
6124 // paused or unresponsive, then all looks good to
6125 // handle the event.
6126 if (targetIsNew && !targetWin.mToken.paused) {
6127 return targetWin;
6128 }
Romain Guy06882f82009-06-10 13:36:04 -07006129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 // If we didn't find a target window, and there is no
6131 // focused app window, then just eat the events.
6132 } else if (mFocusedApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006133 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006134 "Skipping event; no focused app: "
6135 + nextKey + " " + nextMotion);
6136 return null;
6137 }
6138 }
Romain Guy06882f82009-06-10 13:36:04 -07006139
Joe Onorato8a9b2202010-02-26 18:56:32 -08006140 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 TAG, "Waiting for last key in " + mLastBinder
6142 + " target=" + targetWin
6143 + " mFinished=" + mFinished
6144 + " mDisplayFrozen=" + mDisplayFrozen
6145 + " targetIsNew=" + targetIsNew
6146 + " paused="
6147 + (targetWin != null ? targetWin.mToken.paused : false)
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006148 + " mFocusedApp=" + mFocusedApp
6149 + " mCurrentFocus=" + mCurrentFocus);
Romain Guy06882f82009-06-10 13:36:04 -07006150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 targetApp = targetWin != null
6152 ? targetWin.mAppToken : mFocusedApp;
Romain Guy06882f82009-06-10 13:36:04 -07006153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 long curTimeout = keyDispatchingTimeout;
6155 if (mTimeToSwitch != 0) {
6156 long now = SystemClock.uptimeMillis();
6157 if (mTimeToSwitch <= now) {
6158 // If an app switch key has been pressed, and we have
6159 // waited too long for the current app to finish
6160 // processing keys, then wait no more!
Christopher Tate136b1f92010-02-11 17:51:24 -08006161 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 continue;
6163 }
6164 long switchTimeout = mTimeToSwitch - now;
6165 if (curTimeout > switchTimeout) {
6166 curTimeout = switchTimeout;
6167 }
6168 }
Romain Guy06882f82009-06-10 13:36:04 -07006169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006170 try {
6171 // after that continue
6172 // processing keys, so we don't get stuck.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006173 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006174 TAG, "Waiting for key dispatch: " + curTimeout);
6175 wait(curTimeout);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006176 if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 + SystemClock.uptimeMillis() + " startTime="
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006178 + startTime + " switchTime=" + mTimeToSwitch
6179 + " target=" + targetWin + " mLW=" + mLastWin
6180 + " mLB=" + mLastBinder + " fin=" + mFinished
6181 + " mCurrentFocus=" + mCurrentFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006182 } catch (InterruptedException e) {
6183 }
6184 }
6185
6186 // If we were frozen during configuration change, restart the
6187 // timeout checks from now; otherwise look at whether we timed
6188 // out before awakening.
6189 if (mWasFrozen) {
6190 waitedFor = 0;
6191 mWasFrozen = false;
6192 } else {
6193 waitedFor = SystemClock.uptimeMillis() - startTime;
6194 }
6195
6196 if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
6197 IApplicationToken at = null;
6198 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006199 Slog.w(TAG, "Key dispatching timed out sending to " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006200 (targetWin != null ? targetWin.mAttrs.getTitle()
Ken Shirriff8200b202010-02-04 13:34:37 -08006201 : "<null>: no window ready for key dispatch"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 // NOSHIP debugging
Joe Onorato8a9b2202010-02-26 18:56:32 -08006203 Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
6204 Slog.w(TAG, "Current dispatch state: " +
Ken Shirriff8200b202010-02-04 13:34:37 -08006205 new DispatchState(nextKey, targetWin));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006206 // END NOSHIP
6207 //dump();
6208 if (targetWin != null) {
6209 at = targetWin.getAppToken();
6210 } else if (targetApp != null) {
6211 at = targetApp.appToken;
6212 }
6213 }
6214
6215 boolean abort = true;
6216 if (at != null) {
6217 try {
6218 long timeout = at.getKeyDispatchingTimeout();
6219 if (timeout > waitedFor) {
6220 // we did not wait the proper amount of time for this application.
6221 // set the timeout to be the real timeout and wait again.
6222 keyDispatchingTimeout = timeout - waitedFor;
6223 continue;
6224 } else {
6225 abort = at.keyDispatchingTimedOut();
6226 }
6227 } catch (RemoteException ex) {
6228 }
6229 }
6230
6231 synchronized (this) {
6232 if (abort && (mLastWin == targetWin || targetWin == null)) {
6233 mFinished = true;
Romain Guy06882f82009-06-10 13:36:04 -07006234 if (mLastWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006235 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 "Window " + mLastWin +
6237 " timed out on key input");
6238 if (mLastWin.mToken.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006239 Slog.w(TAG, "Un-pausing dispatching to this window");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 mLastWin.mToken.paused = false;
6241 }
6242 }
6243 if (mMotionTarget == targetWin) {
6244 mMotionTarget = null;
6245 }
6246 mLastWin = null;
6247 mLastBinder = null;
6248 if (failIfTimeout || targetWin == null) {
6249 return null;
6250 }
6251 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006252 Slog.w(TAG, "Continuing to wait for key to be dispatched");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 startTime = SystemClock.uptimeMillis();
6254 }
6255 }
6256 }
6257 }
6258 }
Romain Guy06882f82009-06-10 13:36:04 -07006259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006261 MotionEvent nextMotion, boolean isPointerEvent,
6262 int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 mOutsideTouchTargets = null;
Romain Guy06882f82009-06-10 13:36:04 -07006264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 if (nextKey != null) {
6266 // Find the target window for a normal key event.
6267 final int keycode = nextKey.getKeyCode();
6268 final int repeatCount = nextKey.getRepeatCount();
6269 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
6270 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006272 if (!dispatch) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006273 if (callingUid == 0 ||
6274 mContext.checkPermission(
6275 android.Manifest.permission.INJECT_EVENTS,
6276 callingPid, callingUid)
6277 == PackageManager.PERMISSION_GRANTED) {
6278 mPolicy.interceptKeyTi(null, keycode,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006279 nextKey.getMetaState(), down, repeatCount,
6280 nextKey.getFlags());
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006281 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006282 Slog.w(TAG, "Event timeout during app switch: dropping "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 + nextKey);
6284 return SKIP_TARGET_TOKEN;
6285 }
Romain Guy06882f82009-06-10 13:36:04 -07006286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
Romain Guy06882f82009-06-10 13:36:04 -07006288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 WindowState focus = null;
6290 synchronized(mWindowMap) {
6291 focus = getFocusedWindowLocked();
6292 }
Romain Guy06882f82009-06-10 13:36:04 -07006293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
Romain Guy06882f82009-06-10 13:36:04 -07006295
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006296 if (callingUid == 0 ||
6297 (focus != null && callingUid == focus.mSession.mUid) ||
6298 mContext.checkPermission(
6299 android.Manifest.permission.INJECT_EVENTS,
6300 callingPid, callingUid)
6301 == PackageManager.PERMISSION_GRANTED) {
6302 if (mPolicy.interceptKeyTi(focus,
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006303 keycode, nextKey.getMetaState(), down, repeatCount,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006304 nextKey.getFlags())) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006305 return CONSUMED_EVENT_TOKEN;
6306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 }
Romain Guy06882f82009-06-10 13:36:04 -07006308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 return focus;
Romain Guy06882f82009-06-10 13:36:04 -07006310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006311 } else if (!isPointerEvent) {
6312 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
6313 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006314 Slog.w(TAG, "Event timeout during app switch: dropping trackball "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006315 + nextMotion);
6316 return SKIP_TARGET_TOKEN;
6317 }
Romain Guy06882f82009-06-10 13:36:04 -07006318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 WindowState focus = null;
6320 synchronized(mWindowMap) {
6321 focus = getFocusedWindowLocked();
6322 }
Romain Guy06882f82009-06-10 13:36:04 -07006323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006324 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
6325 return focus;
6326 }
Romain Guy06882f82009-06-10 13:36:04 -07006327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006328 if (nextMotion == null) {
6329 return SKIP_TARGET_TOKEN;
6330 }
Romain Guy06882f82009-06-10 13:36:04 -07006331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
6333 KeyEvent.KEYCODE_UNKNOWN);
6334 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006335 Slog.w(TAG, "Event timeout during app switch: dropping pointer "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 + nextMotion);
6337 return SKIP_TARGET_TOKEN;
6338 }
Romain Guy06882f82009-06-10 13:36:04 -07006339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340 // Find the target window for a pointer event.
6341 int action = nextMotion.getAction();
6342 final float xf = nextMotion.getX();
6343 final float yf = nextMotion.getY();
6344 final long eventTime = nextMotion.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07006345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 final boolean screenWasOff = qev != null
6347 && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07006348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 WindowState target = null;
Romain Guy06882f82009-06-10 13:36:04 -07006350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006351 synchronized(mWindowMap) {
6352 synchronized (this) {
6353 if (action == MotionEvent.ACTION_DOWN) {
6354 if (mMotionTarget != null) {
6355 // this is weird, we got a pen down, but we thought it was
6356 // already down!
6357 // XXX: We should probably send an ACTION_UP to the current
6358 // target.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006359 Slog.w(TAG, "Pointer down received while already down in: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006360 + mMotionTarget);
6361 mMotionTarget = null;
6362 }
Romain Guy06882f82009-06-10 13:36:04 -07006363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006364 // ACTION_DOWN is special, because we need to lock next events to
6365 // the window we'll land onto.
6366 final int x = (int)xf;
6367 final int y = (int)yf;
Romain Guy06882f82009-06-10 13:36:04 -07006368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006369 final ArrayList windows = mWindows;
6370 final int N = windows.size();
6371 WindowState topErrWindow = null;
6372 final Rect tmpRect = mTempRect;
6373 for (int i=N-1; i>=0; i--) {
6374 WindowState child = (WindowState)windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006375 //Slog.i(TAG, "Checking dispatch to: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006376 final int flags = child.mAttrs.flags;
6377 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
6378 if (topErrWindow == null) {
6379 topErrWindow = child;
6380 }
6381 }
6382 if (!child.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006383 //Slog.i(TAG, "Not visible!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 continue;
6385 }
6386 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006387 //Slog.i(TAG, "Not touchable!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 if ((flags & WindowManager.LayoutParams
6389 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6390 child.mNextOutsideTouch = mOutsideTouchTargets;
6391 mOutsideTouchTargets = child;
6392 }
6393 continue;
6394 }
6395 tmpRect.set(child.mFrame);
6396 if (child.mTouchableInsets == ViewTreeObserver
6397 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
6398 // The touch is inside of the window if it is
6399 // inside the frame, AND the content part of that
6400 // frame that was given by the application.
6401 tmpRect.left += child.mGivenContentInsets.left;
6402 tmpRect.top += child.mGivenContentInsets.top;
6403 tmpRect.right -= child.mGivenContentInsets.right;
6404 tmpRect.bottom -= child.mGivenContentInsets.bottom;
6405 } else if (child.mTouchableInsets == ViewTreeObserver
6406 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
6407 // The touch is inside of the window if it is
6408 // inside the frame, AND the visible part of that
6409 // frame that was given by the application.
6410 tmpRect.left += child.mGivenVisibleInsets.left;
6411 tmpRect.top += child.mGivenVisibleInsets.top;
6412 tmpRect.right -= child.mGivenVisibleInsets.right;
6413 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
6414 }
6415 final int touchFlags = flags &
6416 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6417 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
6418 if (tmpRect.contains(x, y) || touchFlags == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006419 //Slog.i(TAG, "Using this target!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 if (!screenWasOff || (flags &
6421 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
6422 mMotionTarget = child;
6423 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006424 //Slog.i(TAG, "Waking, skip!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 mMotionTarget = null;
6426 }
6427 break;
6428 }
Romain Guy06882f82009-06-10 13:36:04 -07006429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 if ((flags & WindowManager.LayoutParams
6431 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6432 child.mNextOutsideTouch = mOutsideTouchTargets;
6433 mOutsideTouchTargets = child;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006434 //Slog.i(TAG, "Adding to outside target list: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006435 }
6436 }
6437
6438 // if there's an error window but it's not accepting
6439 // focus (typically because it is not yet visible) just
6440 // wait for it -- any other focused window may in fact
6441 // be in ANR state.
6442 if (topErrWindow != null && mMotionTarget != topErrWindow) {
6443 mMotionTarget = null;
6444 }
6445 }
Romain Guy06882f82009-06-10 13:36:04 -07006446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 target = mMotionTarget;
6448 }
6449 }
Romain Guy06882f82009-06-10 13:36:04 -07006450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006451 wakeupIfNeeded(target, eventType(nextMotion));
Romain Guy06882f82009-06-10 13:36:04 -07006452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 // Pointer events are a little different -- if there isn't a
6454 // target found for any event, then just drop it.
6455 return target != null ? target : SKIP_TARGET_TOKEN;
6456 }
Romain Guy06882f82009-06-10 13:36:04 -07006457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006458 boolean checkShouldDispatchKey(int keycode) {
6459 synchronized (this) {
6460 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
6461 mTimeToSwitch = 0;
6462 return true;
6463 }
6464 if (mTimeToSwitch != 0
6465 && mTimeToSwitch < SystemClock.uptimeMillis()) {
6466 return false;
6467 }
6468 return true;
6469 }
6470 }
Romain Guy06882f82009-06-10 13:36:04 -07006471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006472 void bindTargetWindowLocked(WindowState win,
6473 int pendingWhat, QueuedEvent pendingMotion) {
6474 synchronized (this) {
6475 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
6476 }
6477 }
Romain Guy06882f82009-06-10 13:36:04 -07006478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 void bindTargetWindowLocked(WindowState win) {
6480 synchronized (this) {
6481 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
6482 }
6483 }
6484
6485 void bindTargetWindowLockedLocked(WindowState win,
6486 int pendingWhat, QueuedEvent pendingMotion) {
6487 mLastWin = win;
6488 mLastBinder = win.mClient.asBinder();
6489 mFinished = false;
6490 if (pendingMotion != null) {
6491 final Session s = win.mSession;
6492 if (pendingWhat == RETURN_PENDING_POINTER) {
6493 releasePendingPointerLocked(s);
6494 s.mPendingPointerMove = pendingMotion;
6495 s.mPendingPointerWindow = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006496 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 "bindTargetToWindow " + s.mPendingPointerMove);
6498 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
6499 releasePendingTrackballLocked(s);
6500 s.mPendingTrackballMove = pendingMotion;
6501 s.mPendingTrackballWindow = win;
6502 }
6503 }
6504 }
Romain Guy06882f82009-06-10 13:36:04 -07006505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 void releasePendingPointerLocked(Session s) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006507 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006508 "releasePendingPointer " + s.mPendingPointerMove);
6509 if (s.mPendingPointerMove != null) {
6510 mQueue.recycleEvent(s.mPendingPointerMove);
6511 s.mPendingPointerMove = null;
6512 }
6513 }
Romain Guy06882f82009-06-10 13:36:04 -07006514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 void releasePendingTrackballLocked(Session s) {
6516 if (s.mPendingTrackballMove != null) {
6517 mQueue.recycleEvent(s.mPendingTrackballMove);
6518 s.mPendingTrackballMove = null;
6519 }
6520 }
Romain Guy06882f82009-06-10 13:36:04 -07006521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006522 MotionEvent finishedKey(Session session, IWindow client, boolean force,
6523 int returnWhat) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006524 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006525 TAG, "finishedKey: client=" + client + ", force=" + force);
6526
6527 if (client == null) {
6528 return null;
6529 }
6530
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006531 MotionEvent res = null;
6532 QueuedEvent qev = null;
6533 WindowState win = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006536 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006537 TAG, "finishedKey: client=" + client.asBinder()
6538 + ", force=" + force + ", last=" + mLastBinder
6539 + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
6540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006541 if (returnWhat == RETURN_PENDING_POINTER) {
6542 qev = session.mPendingPointerMove;
6543 win = session.mPendingPointerWindow;
6544 session.mPendingPointerMove = null;
6545 session.mPendingPointerWindow = null;
6546 } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
6547 qev = session.mPendingTrackballMove;
6548 win = session.mPendingTrackballWindow;
6549 session.mPendingTrackballMove = null;
6550 session.mPendingTrackballWindow = null;
6551 }
Romain Guy06882f82009-06-10 13:36:04 -07006552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006553 if (mLastBinder == client.asBinder()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006554 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006555 TAG, "finishedKey: last paused="
6556 + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
6557 if (mLastWin != null && (!mLastWin.mToken.paused || force
6558 || !mEventDispatching)) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006559 doFinishedKeyLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560 } else {
6561 // Make sure to wake up anyone currently waiting to
6562 // dispatch a key, so they can re-evaluate their
6563 // current situation.
6564 mFinished = true;
6565 notifyAll();
6566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 }
Romain Guy06882f82009-06-10 13:36:04 -07006568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 if (qev != null) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006570 res = (MotionEvent)qev.event;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006571 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006572 "Returning pending motion: " + res);
6573 mQueue.recycleEvent(qev);
6574 if (win != null && returnWhat == RETURN_PENDING_POINTER) {
6575 res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
6576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006577 }
Christopher Tate2624fbc2009-12-11 12:11:31 -08006578 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006579
Christopher Tate2624fbc2009-12-11 12:11:31 -08006580 if (res != null && returnWhat == RETURN_PENDING_POINTER) {
6581 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08006582 dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006583 }
6584 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006585
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006586 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006587 }
6588
6589 void tickle() {
6590 synchronized (this) {
6591 notifyAll();
6592 }
6593 }
Romain Guy06882f82009-06-10 13:36:04 -07006594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 void handleNewWindowLocked(WindowState newWindow) {
6596 if (!newWindow.canReceiveKeys()) {
6597 return;
6598 }
6599 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006600 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 TAG, "New key dispatch window: win="
6602 + newWindow.mClient.asBinder()
6603 + ", last=" + mLastBinder
6604 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6605 + "), finished=" + mFinished + ", paused="
6606 + newWindow.mToken.paused);
6607
6608 // Displaying a window implicitly causes dispatching to
6609 // be unpaused. (This is to protect against bugs if someone
6610 // pauses dispatching but forgets to resume.)
6611 newWindow.mToken.paused = false;
6612
6613 mGotFirstWindow = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614
6615 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006616 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 "New SYSTEM_ERROR window; resetting state");
6618 mLastWin = null;
6619 mLastBinder = null;
6620 mMotionTarget = null;
6621 mFinished = true;
6622 } else if (mLastWin != null) {
6623 // If the new window is above the window we are
6624 // waiting on, then stop waiting and let key dispatching
6625 // start on the new guy.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006626 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 TAG, "Last win layer=" + mLastWin.mLayer
6628 + ", new win layer=" + newWindow.mLayer);
6629 if (newWindow.mLayer >= mLastWin.mLayer) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006630 // The new window is above the old; finish pending input to the last
6631 // window and start directing it to the new one.
6632 mLastWin.mToken.paused = false;
Christopher Tate136b1f92010-02-11 17:51:24 -08006633 doFinishedKeyLocked(false); // does a notifyAll()
6634 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006635 }
6636 }
6637
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006638 // Now that we've put a new window state in place, make the event waiter
6639 // take notice and retarget its attentions.
6640 notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 }
6642 }
6643
6644 void pauseDispatchingLocked(WindowToken token) {
6645 synchronized (this)
6646 {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006647 if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 token.paused = true;
6649
6650 /*
6651 if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
6652 mPaused = true;
6653 } else {
6654 if (mLastWin == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006655 Slog.i(TAG, "Key dispatching not paused: no last window.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 } else if (mFinished) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006657 Slog.i(TAG, "Key dispatching not paused: finished last key.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006659 Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 }
6661 }
6662 */
6663 }
6664 }
6665
6666 void resumeDispatchingLocked(WindowToken token) {
6667 synchronized (this) {
6668 if (token.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006669 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006670 TAG, "Resuming WindowToken " + token
6671 + ", last=" + mLastBinder
6672 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6673 + "), finished=" + mFinished + ", paused="
6674 + token.paused);
6675 token.paused = false;
6676 if (mLastWin != null && mLastWin.mToken == token && mFinished) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006677 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 } else {
6679 notifyAll();
6680 }
6681 }
6682 }
6683 }
6684
6685 void setEventDispatchingLocked(boolean enabled) {
6686 synchronized (this) {
6687 mEventDispatching = enabled;
6688 notifyAll();
6689 }
6690 }
Romain Guy06882f82009-06-10 13:36:04 -07006691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 void appSwitchComing() {
6693 synchronized (this) {
6694 // Don't wait for more than .5 seconds for app to finish
6695 // processing the pending events.
6696 long now = SystemClock.uptimeMillis() + 500;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006697 if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
6699 mTimeToSwitch = now;
6700 }
6701 notifyAll();
6702 }
6703 }
Romain Guy06882f82009-06-10 13:36:04 -07006704
Christopher Tate136b1f92010-02-11 17:51:24 -08006705 private final void doFinishedKeyLocked(boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006706 if (mLastWin != null) {
6707 releasePendingPointerLocked(mLastWin.mSession);
6708 releasePendingTrackballLocked(mLastWin.mSession);
6709 }
Romain Guy06882f82009-06-10 13:36:04 -07006710
Christopher Tate136b1f92010-02-11 17:51:24 -08006711 if (force || mLastWin == null || !mLastWin.mToken.paused
6712 || !mLastWin.isVisibleLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 // If the current window has been paused, we aren't -really-
6714 // finished... so let the waiters still wait.
6715 mLastWin = null;
6716 mLastBinder = null;
6717 }
6718 mFinished = true;
6719 notifyAll();
6720 }
6721 }
6722
6723 private class KeyQ extends KeyInputQueue
6724 implements KeyInputQueue.FilterCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006725 KeyQ() {
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006726 super(mContext, WindowManagerService.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 }
6728
6729 @Override
6730 boolean preprocessEvent(InputDevice device, RawInputEvent event) {
6731 if (mPolicy.preprocessInputEventTq(event)) {
6732 return true;
6733 }
Romain Guy06882f82009-06-10 13:36:04 -07006734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006735 switch (event.type) {
6736 case RawInputEvent.EV_KEY: {
6737 // XXX begin hack
6738 if (DEBUG) {
6739 if (event.keycode == KeyEvent.KEYCODE_G) {
6740 if (event.value != 0) {
6741 // G down
6742 mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
6743 }
6744 return false;
6745 }
6746 if (event.keycode == KeyEvent.KEYCODE_D) {
6747 if (event.value != 0) {
6748 //dump();
6749 }
6750 return false;
6751 }
6752 }
6753 // XXX end hack
Romain Guy06882f82009-06-10 13:36:04 -07006754
Charles Mendis322591c2009-10-29 11:06:59 -07006755 boolean screenIsOff = !mPowerManager.isScreenOn();
6756 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
Romain Guy06882f82009-06-10 13:36:04 -07006758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006759 if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
6760 mPowerManager.goToSleep(event.when);
6761 }
6762
6763 if (screenIsOff) {
6764 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6765 }
6766 if (screenIsDim) {
6767 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6768 }
6769 if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
6770 mPowerManager.userActivity(event.when, false,
Michael Chane96440f2009-05-06 10:27:36 -07006771 LocalPowerManager.BUTTON_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 }
Romain Guy06882f82009-06-10 13:36:04 -07006773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774 if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
6775 if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
6776 filterQueue(this);
6777 mKeyWaiter.appSwitchComing();
6778 }
6779 return true;
6780 } else {
6781 return false;
6782 }
6783 }
Romain Guy06882f82009-06-10 13:36:04 -07006784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 case RawInputEvent.EV_REL: {
Charles Mendis322591c2009-10-29 11:06:59 -07006786 boolean screenIsOff = !mPowerManager.isScreenOn();
6787 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 if (screenIsOff) {
6789 if (!mPolicy.isWakeRelMovementTq(event.deviceId,
6790 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006791 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 return false;
6793 }
6794 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6795 }
6796 if (screenIsDim) {
6797 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6798 }
6799 return true;
6800 }
Romain Guy06882f82009-06-10 13:36:04 -07006801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 case RawInputEvent.EV_ABS: {
Charles Mendis322591c2009-10-29 11:06:59 -07006803 boolean screenIsOff = !mPowerManager.isScreenOn();
6804 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 if (screenIsOff) {
6806 if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
6807 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006808 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006809 return false;
6810 }
6811 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6812 }
6813 if (screenIsDim) {
6814 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6815 }
6816 return true;
6817 }
Romain Guy06882f82009-06-10 13:36:04 -07006818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 default:
6820 return true;
6821 }
6822 }
6823
6824 public int filterEvent(QueuedEvent ev) {
6825 switch (ev.classType) {
6826 case RawInputEvent.CLASS_KEYBOARD:
6827 KeyEvent ke = (KeyEvent)ev.event;
6828 if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006829 Slog.w(TAG, "Dropping movement key during app switch: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006830 + ke.getKeyCode() + ", action=" + ke.getAction());
6831 return FILTER_REMOVE;
6832 }
6833 return FILTER_ABORT;
6834 default:
6835 return FILTER_KEEP;
6836 }
6837 }
Michael Chan53071d62009-05-13 17:29:48 -07006838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839
6840 public boolean detectSafeMode() {
6841 mSafeMode = mPolicy.detectSafeMode();
6842 return mSafeMode;
6843 }
Romain Guy06882f82009-06-10 13:36:04 -07006844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 public void systemReady() {
6846 mPolicy.systemReady();
6847 }
Romain Guy06882f82009-06-10 13:36:04 -07006848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006849 private final class InputDispatcherThread extends Thread {
6850 // Time to wait when there is nothing to do: 9999 seconds.
6851 static final int LONG_WAIT=9999*1000;
6852
6853 public InputDispatcherThread() {
6854 super("InputDispatcher");
6855 }
Romain Guy06882f82009-06-10 13:36:04 -07006856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 @Override
6858 public void run() {
6859 while (true) {
6860 try {
6861 process();
6862 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006863 Slog.e(TAG, "Exception in input dispatcher", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006864 }
6865 }
6866 }
Romain Guy06882f82009-06-10 13:36:04 -07006867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 private void process() {
6869 android.os.Process.setThreadPriority(
6870 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -07006871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 // The last key event we saw
6873 KeyEvent lastKey = null;
6874
6875 // Last keydown time for auto-repeating keys
6876 long lastKeyTime = SystemClock.uptimeMillis();
6877 long nextKeyTime = lastKeyTime+LONG_WAIT;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006878 long downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879
Romain Guy06882f82009-06-10 13:36:04 -07006880 // How many successive repeats we generated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 int keyRepeatCount = 0;
6882
6883 // Need to report that configuration has changed?
6884 boolean configChanged = false;
Romain Guy06882f82009-06-10 13:36:04 -07006885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 while (true) {
6887 long curTime = SystemClock.uptimeMillis();
6888
Joe Onorato8a9b2202010-02-26 18:56:32 -08006889 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 TAG, "Waiting for next key: now=" + curTime
6891 + ", repeat @ " + nextKeyTime);
6892
6893 // Retrieve next event, waiting only as long as the next
6894 // repeat timeout. If the configuration has changed, then
6895 // don't wait at all -- we'll report the change as soon as
6896 // we have processed all events.
6897 QueuedEvent ev = mQueue.getEvent(
6898 (int)((!configChanged && curTime < nextKeyTime)
6899 ? (nextKeyTime-curTime) : 0));
6900
Joe Onorato8a9b2202010-02-26 18:56:32 -08006901 if (DEBUG_INPUT && ev != null) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 TAG, "Event: type=" + ev.classType + " data=" + ev.event);
6903
Michael Chan53071d62009-05-13 17:29:48 -07006904 if (MEASURE_LATENCY) {
6905 lt.sample("2 got event ", System.nanoTime() - ev.whenNano);
6906 }
6907
Mike Lockwood3d0ea722009-10-21 22:58:29 -04006908 if (lastKey != null && !mPolicy.allowKeyRepeat()) {
6909 // cancel key repeat at the request of the policy.
6910 lastKey = null;
6911 downTime = 0;
6912 lastKeyTime = curTime;
6913 nextKeyTime = curTime + LONG_WAIT;
6914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006915 try {
6916 if (ev != null) {
Michael Chan53071d62009-05-13 17:29:48 -07006917 curTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 int eventType;
6919 if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
6920 eventType = eventType((MotionEvent)ev.event);
6921 } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
6922 ev.classType == RawInputEvent.CLASS_TRACKBALL) {
6923 eventType = LocalPowerManager.BUTTON_EVENT;
6924 } else {
6925 eventType = LocalPowerManager.OTHER_EVENT;
6926 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006927 try {
Michael Chan53071d62009-05-13 17:29:48 -07006928 if ((curTime - mLastBatteryStatsCallTime)
Michael Chane96440f2009-05-06 10:27:36 -07006929 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
Michael Chan53071d62009-05-13 17:29:48 -07006930 mLastBatteryStatsCallTime = curTime;
Michael Chane96440f2009-05-06 10:27:36 -07006931 mBatteryStats.noteInputEvent();
6932 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006933 } catch (RemoteException e) {
6934 // Ignore
6935 }
Michael Chane10de972009-05-18 11:24:50 -07006936
Mike Lockwood5db42402009-11-30 14:51:51 -05006937 if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
6938 // do not wake screen in this case
6939 } else if (eventType != TOUCH_EVENT
Michael Chane10de972009-05-18 11:24:50 -07006940 && eventType != LONG_TOUCH_EVENT
6941 && eventType != CHEEK_EVENT) {
6942 mPowerManager.userActivity(curTime, false,
6943 eventType, false);
6944 } else if (mLastTouchEventType != eventType
6945 || (curTime - mLastUserActivityCallTime)
6946 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
6947 mLastUserActivityCallTime = curTime;
6948 mLastTouchEventType = eventType;
6949 mPowerManager.userActivity(curTime, false,
6950 eventType, false);
6951 }
6952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 switch (ev.classType) {
6954 case RawInputEvent.CLASS_KEYBOARD:
6955 KeyEvent ke = (KeyEvent)ev.event;
6956 if (ke.isDown()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 lastKeyTime = curTime;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006958 if (lastKey != null &&
6959 ke.getKeyCode() == lastKey.getKeyCode()) {
6960 keyRepeatCount++;
6961 // Arbitrary long timeout to block
6962 // repeating here since we know that
6963 // the device driver takes care of it.
6964 nextKeyTime = lastKeyTime + LONG_WAIT;
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07006965 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006966 TAG, "Received repeated key down");
6967 } else {
6968 downTime = curTime;
6969 keyRepeatCount = 0;
6970 nextKeyTime = lastKeyTime
6971 + ViewConfiguration.getLongPressTimeout();
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07006972 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006973 TAG, "Received key down: first repeat @ "
6974 + nextKeyTime);
6975 }
6976 lastKey = ke;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 } else {
6978 lastKey = null;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07006979 downTime = 0;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006980 keyRepeatCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006981 // Arbitrary long timeout.
6982 lastKeyTime = curTime;
6983 nextKeyTime = curTime + LONG_WAIT;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006984 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 TAG, "Received key up: ignore repeat @ "
6986 + nextKeyTime);
6987 }
Kristian Dreher133bfdf2010-02-23 08:50:58 +01006988 if (keyRepeatCount > 0) {
6989 dispatchKey(KeyEvent.changeTimeRepeat(ke,
6990 ke.getEventTime(), keyRepeatCount), 0, 0);
6991 } else {
6992 dispatchKey(ke, 0, 0);
6993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006994 mQueue.recycleEvent(ev);
6995 break;
6996 case RawInputEvent.CLASS_TOUCHSCREEN:
Joe Onorato8a9b2202010-02-26 18:56:32 -08006997 //Slog.i(TAG, "Read next event " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006998 dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
6999 break;
7000 case RawInputEvent.CLASS_TRACKBALL:
7001 dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
7002 break;
7003 case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
7004 configChanged = true;
7005 break;
7006 default:
7007 mQueue.recycleEvent(ev);
7008 break;
7009 }
Romain Guy06882f82009-06-10 13:36:04 -07007010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007011 } else if (configChanged) {
7012 configChanged = false;
7013 sendNewConfiguration();
Romain Guy06882f82009-06-10 13:36:04 -07007014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 } else if (lastKey != null) {
7016 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 // Timeout occurred while key was down. If it is at or
7019 // past the key repeat time, dispatch the repeat.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007020 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 TAG, "Key timeout: repeat=" + nextKeyTime
7022 + ", now=" + curTime);
7023 if (curTime < nextKeyTime) {
7024 continue;
7025 }
Romain Guy06882f82009-06-10 13:36:04 -07007026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 lastKeyTime = nextKeyTime;
7028 nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
7029 keyRepeatCount++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007030 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 TAG, "Key repeat: count=" + keyRepeatCount
7032 + ", next @ " + nextKeyTime);
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007033 KeyEvent newEvent;
7034 if (downTime != 0 && (downTime
7035 + ViewConfiguration.getLongPressTimeout())
7036 <= curTime) {
7037 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7038 curTime, keyRepeatCount,
7039 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
7040 downTime = 0;
7041 } else {
7042 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7043 curTime, keyRepeatCount);
7044 }
7045 dispatchKey(newEvent, 0, 0);
Romain Guy06882f82009-06-10 13:36:04 -07007046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 } else {
7048 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 lastKeyTime = curTime;
7051 nextKeyTime = curTime + LONG_WAIT;
7052 }
Romain Guy06882f82009-06-10 13:36:04 -07007053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007054 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007055 Slog.e(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 "Input thread received uncaught exception: " + e, e);
7057 }
7058 }
7059 }
7060 }
7061
7062 // -------------------------------------------------------------
7063 // Client Session State
7064 // -------------------------------------------------------------
7065
7066 private final class Session extends IWindowSession.Stub
7067 implements IBinder.DeathRecipient {
7068 final IInputMethodClient mClient;
7069 final IInputContext mInputContext;
7070 final int mUid;
7071 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007072 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007073 SurfaceSession mSurfaceSession;
7074 int mNumWindow = 0;
7075 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07007076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007077 /**
7078 * Current pointer move event being dispatched to client window... must
7079 * hold key lock to access.
7080 */
7081 QueuedEvent mPendingPointerMove;
7082 WindowState mPendingPointerWindow;
Romain Guy06882f82009-06-10 13:36:04 -07007083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007084 /**
7085 * Current trackball move event being dispatched to client window... must
7086 * hold key lock to access.
7087 */
7088 QueuedEvent mPendingTrackballMove;
7089 WindowState mPendingTrackballWindow;
7090
7091 public Session(IInputMethodClient client, IInputContext inputContext) {
7092 mClient = client;
7093 mInputContext = inputContext;
7094 mUid = Binder.getCallingUid();
7095 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007096 StringBuilder sb = new StringBuilder();
7097 sb.append("Session{");
7098 sb.append(Integer.toHexString(System.identityHashCode(this)));
7099 sb.append(" uid ");
7100 sb.append(mUid);
7101 sb.append("}");
7102 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07007103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007104 synchronized (mWindowMap) {
7105 if (mInputMethodManager == null && mHaveInputMethods) {
7106 IBinder b = ServiceManager.getService(
7107 Context.INPUT_METHOD_SERVICE);
7108 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
7109 }
7110 }
7111 long ident = Binder.clearCallingIdentity();
7112 try {
7113 // Note: it is safe to call in to the input method manager
7114 // here because we are not holding our lock.
7115 if (mInputMethodManager != null) {
7116 mInputMethodManager.addClient(client, inputContext,
7117 mUid, mPid);
7118 } else {
7119 client.setUsingInputMethod(false);
7120 }
7121 client.asBinder().linkToDeath(this, 0);
7122 } catch (RemoteException e) {
7123 // The caller has died, so we can just forget about this.
7124 try {
7125 if (mInputMethodManager != null) {
7126 mInputMethodManager.removeClient(client);
7127 }
7128 } catch (RemoteException ee) {
7129 }
7130 } finally {
7131 Binder.restoreCallingIdentity(ident);
7132 }
7133 }
Romain Guy06882f82009-06-10 13:36:04 -07007134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007135 @Override
7136 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
7137 throws RemoteException {
7138 try {
7139 return super.onTransact(code, data, reply, flags);
7140 } catch (RuntimeException e) {
7141 // Log all 'real' exceptions thrown to the caller
7142 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007143 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 }
7145 throw e;
7146 }
7147 }
7148
7149 public void binderDied() {
7150 // Note: it is safe to call in to the input method manager
7151 // here because we are not holding our lock.
7152 try {
7153 if (mInputMethodManager != null) {
7154 mInputMethodManager.removeClient(mClient);
7155 }
7156 } catch (RemoteException e) {
7157 }
7158 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07007159 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007160 mClientDead = true;
7161 killSessionLocked();
7162 }
7163 }
7164
7165 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007166 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
7167 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
7168 outInputChannel);
7169 }
7170
7171 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007172 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007173 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007174 }
Romain Guy06882f82009-06-10 13:36:04 -07007175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007176 public void remove(IWindow window) {
7177 removeWindow(this, window);
7178 }
Romain Guy06882f82009-06-10 13:36:04 -07007179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007180 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
7181 int requestedWidth, int requestedHeight, int viewFlags,
7182 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007183 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 return relayoutWindow(this, window, attrs,
7185 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007186 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 }
Romain Guy06882f82009-06-10 13:36:04 -07007188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 public void setTransparentRegion(IWindow window, Region region) {
7190 setTransparentRegionWindow(this, window, region);
7191 }
Romain Guy06882f82009-06-10 13:36:04 -07007192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 public void setInsets(IWindow window, int touchableInsets,
7194 Rect contentInsets, Rect visibleInsets) {
7195 setInsetsWindow(this, window, touchableInsets, contentInsets,
7196 visibleInsets);
7197 }
Romain Guy06882f82009-06-10 13:36:04 -07007198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007199 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
7200 getWindowDisplayFrame(this, window, outDisplayFrame);
7201 }
Romain Guy06882f82009-06-10 13:36:04 -07007202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007203 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007204 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 TAG, "IWindow finishDrawing called for " + window);
7206 finishDrawingWindow(this, window);
7207 }
7208
7209 public void finishKey(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007210 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 TAG, "IWindow finishKey called for " + window);
7212 mKeyWaiter.finishedKey(this, window, false,
7213 KeyWaiter.RETURN_NOTHING);
7214 }
7215
7216 public MotionEvent getPendingPointerMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007217 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218 TAG, "IWindow getPendingMotionEvent called for " + window);
7219 return mKeyWaiter.finishedKey(this, window, false,
7220 KeyWaiter.RETURN_PENDING_POINTER);
7221 }
Romain Guy06882f82009-06-10 13:36:04 -07007222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 public MotionEvent getPendingTrackballMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007224 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225 TAG, "IWindow getPendingMotionEvent called for " + window);
7226 return mKeyWaiter.finishedKey(this, window, false,
7227 KeyWaiter.RETURN_PENDING_TRACKBALL);
7228 }
7229
7230 public void setInTouchMode(boolean mode) {
7231 synchronized(mWindowMap) {
7232 mInTouchMode = mode;
7233 }
7234 }
7235
7236 public boolean getInTouchMode() {
7237 synchronized(mWindowMap) {
7238 return mInTouchMode;
7239 }
7240 }
7241
7242 public boolean performHapticFeedback(IWindow window, int effectId,
7243 boolean always) {
7244 synchronized(mWindowMap) {
7245 long ident = Binder.clearCallingIdentity();
7246 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007247 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007248 windowForClientLocked(this, window, true),
7249 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007250 } finally {
7251 Binder.restoreCallingIdentity(ident);
7252 }
7253 }
7254 }
Romain Guy06882f82009-06-10 13:36:04 -07007255
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007256 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007257 synchronized(mWindowMap) {
7258 long ident = Binder.clearCallingIdentity();
7259 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007260 setWindowWallpaperPositionLocked(
7261 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007262 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007263 } finally {
7264 Binder.restoreCallingIdentity(ident);
7265 }
7266 }
7267 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007268
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007269 public void wallpaperOffsetsComplete(IBinder window) {
7270 WindowManagerService.this.wallpaperOffsetsComplete(window);
7271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007272
Dianne Hackborn75804932009-10-20 20:15:20 -07007273 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
7274 int z, Bundle extras, boolean sync) {
7275 synchronized(mWindowMap) {
7276 long ident = Binder.clearCallingIdentity();
7277 try {
7278 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007279 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07007280 action, x, y, z, extras, sync);
7281 } finally {
7282 Binder.restoreCallingIdentity(ident);
7283 }
7284 }
7285 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007286
Dianne Hackborn75804932009-10-20 20:15:20 -07007287 public void wallpaperCommandComplete(IBinder window, Bundle result) {
7288 WindowManagerService.this.wallpaperCommandComplete(window, result);
7289 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 void windowAddedLocked() {
7292 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007293 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007294 TAG, "First window added to " + this + ", creating SurfaceSession");
7295 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007296 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007297 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007298 mSessions.add(this);
7299 }
7300 mNumWindow++;
7301 }
7302
7303 void windowRemovedLocked() {
7304 mNumWindow--;
7305 killSessionLocked();
7306 }
Romain Guy06882f82009-06-10 13:36:04 -07007307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 void killSessionLocked() {
7309 if (mNumWindow <= 0 && mClientDead) {
7310 mSessions.remove(this);
7311 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007312 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 TAG, "Last window removed from " + this
7314 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007315 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007316 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007317 try {
7318 mSurfaceSession.kill();
7319 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007320 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 + mSurfaceSession + " in session " + this
7322 + ": " + e.toString());
7323 }
7324 mSurfaceSession = null;
7325 }
7326 }
7327 }
Romain Guy06882f82009-06-10 13:36:04 -07007328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007330 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
7331 pw.print(" mClientDead="); pw.print(mClientDead);
7332 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
7333 if (mPendingPointerWindow != null || mPendingPointerMove != null) {
7334 pw.print(prefix);
7335 pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
7336 pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
7337 }
7338 if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
7339 pw.print(prefix);
7340 pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
7341 pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
7342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 }
7344
7345 @Override
7346 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007347 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007348 }
7349 }
7350
7351 // -------------------------------------------------------------
7352 // Client Window State
7353 // -------------------------------------------------------------
7354
7355 private final class WindowState implements WindowManagerPolicy.WindowState {
7356 final Session mSession;
7357 final IWindow mClient;
7358 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07007359 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007360 AppWindowToken mAppToken;
7361 AppWindowToken mTargetAppToken;
7362 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
7363 final DeathRecipient mDeathRecipient;
7364 final WindowState mAttachedWindow;
7365 final ArrayList mChildWindows = new ArrayList();
7366 final int mBaseLayer;
7367 final int mSubLayer;
7368 final boolean mLayoutAttached;
7369 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007370 final boolean mIsWallpaper;
7371 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 int mViewVisibility;
7373 boolean mPolicyVisibility = true;
7374 boolean mPolicyVisibilityAfterAnim = true;
7375 boolean mAppFreezing;
7376 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007377 boolean mReportDestroySurface;
7378 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 boolean mAttachedHidden; // is our parent window hidden?
7380 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007381 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 int mRequestedWidth;
7383 int mRequestedHeight;
7384 int mLastRequestedWidth;
7385 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 int mLayer;
7387 int mAnimLayer;
7388 int mLastLayer;
7389 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007390 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007391 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392
7393 WindowState mNextOutsideTouch;
Romain Guy06882f82009-06-10 13:36:04 -07007394
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007395 int mLayoutSeq = -1;
7396
7397 Configuration mConfiguration = null;
7398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007399 // Actual frame shown on-screen (may be modified by animation)
7400 final Rect mShownFrame = new Rect();
7401 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007403 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007404 * Set when we have changed the size of the surface, to know that
7405 * we must tell them application to resize (and thus redraw itself).
7406 */
7407 boolean mSurfaceResized;
7408
7409 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 * Insets that determine the actually visible area
7411 */
7412 final Rect mVisibleInsets = new Rect();
7413 final Rect mLastVisibleInsets = new Rect();
7414 boolean mVisibleInsetsChanged;
7415
7416 /**
7417 * Insets that are covered by system windows
7418 */
7419 final Rect mContentInsets = new Rect();
7420 final Rect mLastContentInsets = new Rect();
7421 boolean mContentInsetsChanged;
7422
7423 /**
7424 * Set to true if we are waiting for this window to receive its
7425 * given internal insets before laying out other windows based on it.
7426 */
7427 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07007428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 /**
7430 * These are the content insets that were given during layout for
7431 * this window, to be applied to windows behind it.
7432 */
7433 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 /**
7436 * These are the visible insets that were given during layout for
7437 * this window, to be applied to windows behind it.
7438 */
7439 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007441 /**
7442 * Flag indicating whether the touchable region should be adjusted by
7443 * the visible insets; if false the area outside the visible insets is
7444 * NOT touchable, so we must use those to adjust the frame during hit
7445 * tests.
7446 */
7447 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07007448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 // Current transformation being applied.
7450 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
7451 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
7452 float mHScale=1, mVScale=1;
7453 float mLastHScale=1, mLastVScale=1;
7454 final Matrix mTmpMatrix = new Matrix();
7455
7456 // "Real" frame that the application sees.
7457 final Rect mFrame = new Rect();
7458 final Rect mLastFrame = new Rect();
7459
7460 final Rect mContainingFrame = new Rect();
7461 final Rect mDisplayFrame = new Rect();
7462 final Rect mContentFrame = new Rect();
7463 final Rect mVisibleFrame = new Rect();
7464
7465 float mShownAlpha = 1;
7466 float mAlpha = 1;
7467 float mLastAlpha = 1;
7468
7469 // Set to true if, when the window gets displayed, it should perform
7470 // an enter animation.
7471 boolean mEnterAnimationPending;
7472
7473 // Currently running animation.
7474 boolean mAnimating;
7475 boolean mLocalAnimating;
7476 Animation mAnimation;
7477 boolean mAnimationIsEntrance;
7478 boolean mHasTransformation;
7479 boolean mHasLocalTransformation;
7480 final Transformation mTransformation = new Transformation();
7481
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007482 // If a window showing a wallpaper: the requested offset for the
7483 // wallpaper; if a wallpaper window: the currently applied offset.
7484 float mWallpaperX = -1;
7485 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007486
7487 // If a window showing a wallpaper: what fraction of the offset
7488 // range corresponds to a full virtual screen.
7489 float mWallpaperXStep = -1;
7490 float mWallpaperYStep = -1;
7491
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007492 // Wallpaper windows: pixels offset based on above variables.
7493 int mXOffset;
7494 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 // This is set after IWindowSession.relayout() has been called at
7497 // least once for the window. It allows us to detect the situation
7498 // where we don't yet have a surface, but should have one soon, so
7499 // we can give the window focus before waiting for the relayout.
7500 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 // This is set after the Surface has been created but before the
7503 // window has been drawn. During this time the surface is hidden.
7504 boolean mDrawPending;
7505
7506 // This is set after the window has finished drawing for the first
7507 // time but before its surface is shown. The surface will be
7508 // displayed when the next layout is run.
7509 boolean mCommitDrawPending;
7510
7511 // This is set during the time after the window's drawing has been
7512 // committed, and before its surface is actually shown. It is used
7513 // to delay showing the surface until all windows in a token are ready
7514 // to be shown.
7515 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007517 // Set when the window has been shown in the screen the first time.
7518 boolean mHasDrawn;
7519
7520 // Currently running an exit animation?
7521 boolean mExiting;
7522
7523 // Currently on the mDestroySurface list?
7524 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007526 // Completely remove from window manager after exit animation?
7527 boolean mRemoveOnExit;
7528
7529 // Set when the orientation is changing and this window has not yet
7530 // been updated for the new orientation.
7531 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 // Is this window now (or just being) removed?
7534 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007535
Dianne Hackborn16064f92010-03-25 00:47:24 -07007536 // For debugging, this is the last information given to the surface flinger.
7537 boolean mSurfaceShown;
7538 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7539 int mSurfaceLayer;
7540 float mSurfaceAlpha;
7541
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007542 // Input channel
7543 InputChannel mInputChannel;
7544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 WindowState(Session s, IWindow c, WindowToken token,
7546 WindowState attachedWindow, WindowManager.LayoutParams a,
7547 int viewVisibility) {
7548 mSession = s;
7549 mClient = c;
7550 mToken = token;
7551 mAttrs.copyFrom(a);
7552 mViewVisibility = viewVisibility;
7553 DeathRecipient deathRecipient = new DeathRecipient();
7554 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007555 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007556 TAG, "Window " + this + " client=" + c.asBinder()
7557 + " token=" + token + " (" + mAttrs.token + ")");
7558 try {
7559 c.asBinder().linkToDeath(deathRecipient, 0);
7560 } catch (RemoteException e) {
7561 mDeathRecipient = null;
7562 mAttachedWindow = null;
7563 mLayoutAttached = false;
7564 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007565 mIsWallpaper = false;
7566 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 mBaseLayer = 0;
7568 mSubLayer = 0;
7569 return;
7570 }
7571 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7574 mAttrs.type <= LAST_SUB_WINDOW)) {
7575 // The multiplier here is to reserve space for multiple
7576 // windows in the same type layer.
7577 mBaseLayer = mPolicy.windowTypeToLayerLw(
7578 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7579 + TYPE_LAYER_OFFSET;
7580 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7581 mAttachedWindow = attachedWindow;
7582 mAttachedWindow.mChildWindows.add(this);
7583 mLayoutAttached = mAttrs.type !=
7584 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7585 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7586 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007587 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7588 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 } else {
7590 // The multiplier here is to reserve space for multiple
7591 // windows in the same type layer.
7592 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7593 * TYPE_LAYER_MULTIPLIER
7594 + TYPE_LAYER_OFFSET;
7595 mSubLayer = 0;
7596 mAttachedWindow = null;
7597 mLayoutAttached = false;
7598 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7599 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007600 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7601 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007602 }
7603
7604 WindowState appWin = this;
7605 while (appWin.mAttachedWindow != null) {
7606 appWin = mAttachedWindow;
7607 }
7608 WindowToken appToken = appWin.mToken;
7609 while (appToken.appWindowToken == null) {
7610 WindowToken parent = mTokenMap.get(appToken.token);
7611 if (parent == null || appToken == parent) {
7612 break;
7613 }
7614 appToken = parent;
7615 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007616 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007617 mAppToken = appToken.appWindowToken;
7618
7619 mSurface = null;
7620 mRequestedWidth = 0;
7621 mRequestedHeight = 0;
7622 mLastRequestedWidth = 0;
7623 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007624 mXOffset = 0;
7625 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 mLayer = 0;
7627 mAnimLayer = 0;
7628 mLastLayer = 0;
7629 }
7630
7631 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007632 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 TAG, "Attaching " + this + " token=" + mToken
7634 + ", list=" + mToken.windows);
7635 mSession.windowAddedLocked();
7636 }
7637
7638 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7639 mHaveFrame = true;
7640
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007641 final Rect container = mContainingFrame;
7642 container.set(pf);
7643
7644 final Rect display = mDisplayFrame;
7645 display.set(df);
7646
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007647 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007648 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007649 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7650 display.intersect(mCompatibleScreenFrame);
7651 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007652 }
7653
7654 final int pw = container.right - container.left;
7655 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007656
7657 int w,h;
7658 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7659 w = mAttrs.width < 0 ? pw : mAttrs.width;
7660 h = mAttrs.height< 0 ? ph : mAttrs.height;
7661 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007662 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7663 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007664 }
Romain Guy06882f82009-06-10 13:36:04 -07007665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 final Rect content = mContentFrame;
7667 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 final Rect visible = mVisibleFrame;
7670 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007673 final int fw = frame.width();
7674 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007676 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7677 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7678
7679 Gravity.apply(mAttrs.gravity, w, h, container,
7680 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7681 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7682
7683 //System.out.println("Out: " + mFrame);
7684
7685 // Now make sure the window fits in the overall display.
7686 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688 // Make sure the content and visible frames are inside of the
7689 // final window frame.
7690 if (content.left < frame.left) content.left = frame.left;
7691 if (content.top < frame.top) content.top = frame.top;
7692 if (content.right > frame.right) content.right = frame.right;
7693 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7694 if (visible.left < frame.left) visible.left = frame.left;
7695 if (visible.top < frame.top) visible.top = frame.top;
7696 if (visible.right > frame.right) visible.right = frame.right;
7697 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 final Rect contentInsets = mContentInsets;
7700 contentInsets.left = content.left-frame.left;
7701 contentInsets.top = content.top-frame.top;
7702 contentInsets.right = frame.right-content.right;
7703 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 final Rect visibleInsets = mVisibleInsets;
7706 visibleInsets.left = visible.left-frame.left;
7707 visibleInsets.top = visible.top-frame.top;
7708 visibleInsets.right = frame.right-visible.right;
7709 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007710
Dianne Hackborn284ac932009-08-28 10:34:25 -07007711 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7712 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007713 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007714 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 if (localLOGV) {
7717 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7718 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007719 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 + mRequestedWidth + ", mRequestedheight="
7721 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7722 + "): frame=" + mFrame.toShortString()
7723 + " ci=" + contentInsets.toShortString()
7724 + " vi=" + visibleInsets.toShortString());
7725 //}
7726 }
7727 }
Romain Guy06882f82009-06-10 13:36:04 -07007728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007729 public Rect getFrameLw() {
7730 return mFrame;
7731 }
7732
7733 public Rect getShownFrameLw() {
7734 return mShownFrame;
7735 }
7736
7737 public Rect getDisplayFrameLw() {
7738 return mDisplayFrame;
7739 }
7740
7741 public Rect getContentFrameLw() {
7742 return mContentFrame;
7743 }
7744
7745 public Rect getVisibleFrameLw() {
7746 return mVisibleFrame;
7747 }
7748
7749 public boolean getGivenInsetsPendingLw() {
7750 return mGivenInsetsPending;
7751 }
7752
7753 public Rect getGivenContentInsetsLw() {
7754 return mGivenContentInsets;
7755 }
Romain Guy06882f82009-06-10 13:36:04 -07007756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007757 public Rect getGivenVisibleInsetsLw() {
7758 return mGivenVisibleInsets;
7759 }
Romain Guy06882f82009-06-10 13:36:04 -07007760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 public WindowManager.LayoutParams getAttrs() {
7762 return mAttrs;
7763 }
7764
7765 public int getSurfaceLayer() {
7766 return mLayer;
7767 }
Romain Guy06882f82009-06-10 13:36:04 -07007768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769 public IApplicationToken getAppToken() {
7770 return mAppToken != null ? mAppToken.appToken : null;
7771 }
7772
7773 public boolean hasAppShownWindows() {
7774 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7775 }
7776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007777 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007778 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007779 TAG, "Setting animation in " + this + ": " + anim);
7780 mAnimating = false;
7781 mLocalAnimating = false;
7782 mAnimation = anim;
7783 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7784 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7785 }
7786
7787 public void clearAnimation() {
7788 if (mAnimation != null) {
7789 mAnimating = true;
7790 mLocalAnimating = false;
7791 mAnimation = null;
7792 }
7793 }
Romain Guy06882f82009-06-10 13:36:04 -07007794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795 Surface createSurfaceLocked() {
7796 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007797 mReportDestroySurface = false;
7798 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 mDrawPending = true;
7800 mCommitDrawPending = false;
7801 mReadyToShow = false;
7802 if (mAppToken != null) {
7803 mAppToken.allDrawn = false;
7804 }
7805
7806 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07007807 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 flags |= Surface.PUSH_BUFFERS;
7809 }
7810
7811 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7812 flags |= Surface.SECURE;
7813 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007814 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815 TAG, "Creating surface in session "
7816 + mSession.mSurfaceSession + " window " + this
7817 + " w=" + mFrame.width()
7818 + " h=" + mFrame.height() + " format="
7819 + mAttrs.format + " flags=" + flags);
7820
7821 int w = mFrame.width();
7822 int h = mFrame.height();
7823 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7824 // for a scaled surface, we always want the requested
7825 // size.
7826 w = mRequestedWidth;
7827 h = mRequestedHeight;
7828 }
7829
Romain Guy9825ec62009-10-01 00:58:09 -07007830 // Something is wrong and SurfaceFlinger will not like this,
7831 // try to revert to sane values
7832 if (w <= 0) w = 1;
7833 if (h <= 0) h = 1;
7834
Dianne Hackborn16064f92010-03-25 00:47:24 -07007835 mSurfaceShown = false;
7836 mSurfaceLayer = 0;
7837 mSurfaceAlpha = 1;
7838 mSurfaceX = 0;
7839 mSurfaceY = 0;
7840 mSurfaceW = w;
7841 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007842 try {
7843 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007844 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007845 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007847 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007848 + mSurface + " IN SESSION "
7849 + mSession.mSurfaceSession
7850 + ": pid=" + mSession.mPid + " format="
7851 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007852 + Integer.toHexString(flags)
7853 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007854 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007855 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 reclaimSomeSurfaceMemoryLocked(this, "create");
7857 return null;
7858 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007859 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007860 return null;
7861 }
Romain Guy06882f82009-06-10 13:36:04 -07007862
Joe Onorato8a9b2202010-02-26 18:56:32 -08007863 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007864 TAG, "Got surface: " + mSurface
7865 + ", set left=" + mFrame.left + " top=" + mFrame.top
7866 + ", animLayer=" + mAnimLayer);
7867 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007868 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007869 if (SHOW_TRANSACTIONS) logSurface(this,
7870 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7871 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7872 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007873 }
7874 Surface.openTransaction();
7875 try {
7876 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007877 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007878 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007879 mSurface.setPosition(mSurfaceX, mSurfaceY);
7880 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007881 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007882 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007883 mSurface.hide();
7884 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007885 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007886 mSurface.setFlags(Surface.SURFACE_DITHER,
7887 Surface.SURFACE_DITHER);
7888 }
7889 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007890 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7892 }
7893 mLastHidden = true;
7894 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007895 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007896 Surface.closeTransaction();
7897 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007898 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007899 TAG, "Created surface " + this);
7900 }
7901 return mSurface;
7902 }
Romain Guy06882f82009-06-10 13:36:04 -07007903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007904 void destroySurfaceLocked() {
7905 // Window is no longer on-screen, so can no longer receive
7906 // key events... if we were waiting for it to finish
7907 // handling a key event, the wait is over!
7908 mKeyWaiter.finishedKey(mSession, mClient, true,
7909 KeyWaiter.RETURN_NOTHING);
7910 mKeyWaiter.releasePendingPointerLocked(mSession);
7911 mKeyWaiter.releasePendingTrackballLocked(mSession);
7912
7913 if (mAppToken != null && this == mAppToken.startingWindow) {
7914 mAppToken.startingDisplayed = false;
7915 }
Romain Guy06882f82009-06-10 13:36:04 -07007916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007917 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007918 mDrawPending = false;
7919 mCommitDrawPending = false;
7920 mReadyToShow = false;
7921
7922 int i = mChildWindows.size();
7923 while (i > 0) {
7924 i--;
7925 WindowState c = (WindowState)mChildWindows.get(i);
7926 c.mAttachedHidden = true;
7927 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007928
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007929 if (mReportDestroySurface) {
7930 mReportDestroySurface = false;
7931 mSurfacePendingDestroy = true;
7932 try {
7933 mClient.dispatchGetNewSurface();
7934 // We'll really destroy on the next time around.
7935 return;
7936 } catch (RemoteException e) {
7937 }
7938 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007940 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007941 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007942 RuntimeException e = null;
7943 if (!HIDE_STACK_CRAWLS) {
7944 e = new RuntimeException();
7945 e.fillInStackTrace();
7946 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007947 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007948 + mSurface + ", session " + mSession, e);
7949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007950 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007951 RuntimeException e = null;
7952 if (!HIDE_STACK_CRAWLS) {
7953 e = new RuntimeException();
7954 e.fillInStackTrace();
7955 }
7956 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007957 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007958 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007959 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007960 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007961 + " surface " + mSurface + " session " + mSession
7962 + ": " + e.toString());
7963 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007964
Dianne Hackborn16064f92010-03-25 00:47:24 -07007965 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 }
7968 }
7969
7970 boolean finishDrawingLocked() {
7971 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007972 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007973 TAG, "finishDrawingLocked: " + mSurface);
7974 mCommitDrawPending = true;
7975 mDrawPending = false;
7976 return true;
7977 }
7978 return false;
7979 }
7980
7981 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007982 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007983 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007985 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 }
7987 mCommitDrawPending = false;
7988 mReadyToShow = true;
7989 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7990 final AppWindowToken atoken = mAppToken;
7991 if (atoken == null || atoken.allDrawn || starting) {
7992 performShowLocked();
7993 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007994 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007995 }
7996
7997 // This must be called while inside a transaction.
7998 boolean performShowLocked() {
7999 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008000 RuntimeException e = null;
8001 if (!HIDE_STACK_CRAWLS) {
8002 e = new RuntimeException();
8003 e.fillInStackTrace();
8004 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008005 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
8007 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
8008 }
8009 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008010 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
8011 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008012 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008013 + " during animation: policyVis=" + mPolicyVisibility
8014 + " attHidden=" + mAttachedHidden
8015 + " tok.hiddenRequested="
8016 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07008017 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008018 + (mAppToken != null ? mAppToken.hidden : false)
8019 + " animating=" + mAnimating
8020 + " tok animating="
8021 + (mAppToken != null ? mAppToken.animating : false));
8022 if (!showSurfaceRobustlyLocked(this)) {
8023 return false;
8024 }
8025 mLastAlpha = -1;
8026 mHasDrawn = true;
8027 mLastHidden = false;
8028 mReadyToShow = false;
8029 enableScreenIfNeededLocked();
8030
8031 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07008032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008033 int i = mChildWindows.size();
8034 while (i > 0) {
8035 i--;
8036 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008037 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008038 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008039 if (c.mSurface != null) {
8040 c.performShowLocked();
8041 // It hadn't been shown, which means layout not
8042 // performed on it, so now we want to make sure to
8043 // do a layout. If called from within the transaction
8044 // loop, this will cause it to restart with a new
8045 // layout.
8046 mLayoutNeeded = true;
8047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048 }
8049 }
Romain Guy06882f82009-06-10 13:36:04 -07008050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 if (mAttrs.type != TYPE_APPLICATION_STARTING
8052 && mAppToken != null) {
8053 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008054
Dianne Hackborn248b1882009-09-16 16:46:44 -07008055 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008056 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008057 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008058 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07008059 // If this initial window is animating, stop it -- we
8060 // will do an animation to reveal it from behind the
8061 // starting window, so there is no need for it to also
8062 // be doing its own stuff.
8063 if (mAnimation != null) {
8064 mAnimation = null;
8065 // Make sure we clean up the animation.
8066 mAnimating = true;
8067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 mFinishedStarting.add(mAppToken);
8069 mH.sendEmptyMessage(H.FINISHED_STARTING);
8070 }
8071 mAppToken.updateReportedVisibilityLocked();
8072 }
8073 }
8074 return true;
8075 }
Romain Guy06882f82009-06-10 13:36:04 -07008076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077 // This must be called while inside a transaction. Returns true if
8078 // there is more animation to run.
8079 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008080 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008081 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008083 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
8084 mHasTransformation = true;
8085 mHasLocalTransformation = true;
8086 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008087 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088 TAG, "Starting animation in " + this +
8089 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
8090 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
8091 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
8092 mAnimation.setStartTime(currentTime);
8093 mLocalAnimating = true;
8094 mAnimating = true;
8095 }
8096 mTransformation.clear();
8097 final boolean more = mAnimation.getTransformation(
8098 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008099 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 TAG, "Stepped animation in " + this +
8101 ": more=" + more + ", xform=" + mTransformation);
8102 if (more) {
8103 // we're not done!
8104 return true;
8105 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008106 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008107 TAG, "Finished animation in " + this +
8108 " @ " + currentTime);
8109 mAnimation = null;
8110 //WindowManagerService.this.dump();
8111 }
8112 mHasLocalTransformation = false;
8113 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008114 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008115 // When our app token is animating, we kind-of pretend like
8116 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
8117 // part of this check means that we will only do this if
8118 // our window is not currently exiting, or it is not
8119 // locally animating itself. The idea being that one that
8120 // is exiting and doing a local animation should be removed
8121 // once that animation is done.
8122 mAnimating = true;
8123 mHasTransformation = true;
8124 mTransformation.clear();
8125 return false;
8126 } else if (mHasTransformation) {
8127 // Little trick to get through the path below to act like
8128 // we have finished an animation.
8129 mAnimating = true;
8130 } else if (isAnimating()) {
8131 mAnimating = true;
8132 }
8133 } else if (mAnimation != null) {
8134 // If the display is frozen, and there is a pending animation,
8135 // clear it and make sure we run the cleanup code.
8136 mAnimating = true;
8137 mLocalAnimating = true;
8138 mAnimation = null;
8139 }
Romain Guy06882f82009-06-10 13:36:04 -07008140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008141 if (!mAnimating && !mLocalAnimating) {
8142 return false;
8143 }
8144
Joe Onorato8a9b2202010-02-26 18:56:32 -08008145 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 TAG, "Animation done in " + this + ": exiting=" + mExiting
8147 + ", reportedVisible="
8148 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07008149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 mAnimating = false;
8151 mLocalAnimating = false;
8152 mAnimation = null;
8153 mAnimLayer = mLayer;
8154 if (mIsImWindow) {
8155 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008156 } else if (mIsWallpaper) {
8157 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008159 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 + " anim layer: " + mAnimLayer);
8161 mHasTransformation = false;
8162 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008163 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
8164 if (DEBUG_VISIBILITY) {
8165 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
8166 + mPolicyVisibilityAfterAnim);
8167 }
8168 mPolicyVisibility = mPolicyVisibilityAfterAnim;
8169 if (!mPolicyVisibility) {
8170 if (mCurrentFocus == this) {
8171 mFocusMayChange = true;
8172 }
8173 // Window is no longer visible -- make sure if we were waiting
8174 // for it to be displayed before enabling the display, that
8175 // we allow the display to be enabled now.
8176 enableScreenIfNeededLocked();
8177 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008179 mTransformation.clear();
8180 if (mHasDrawn
8181 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
8182 && mAppToken != null
8183 && mAppToken.firstWindowDrawn
8184 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008185 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186 + mToken + ": first real window done animating");
8187 mFinishedStarting.add(mAppToken);
8188 mH.sendEmptyMessage(H.FINISHED_STARTING);
8189 }
Romain Guy06882f82009-06-10 13:36:04 -07008190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008191 finishExit();
8192
8193 if (mAppToken != null) {
8194 mAppToken.updateReportedVisibilityLocked();
8195 }
8196
8197 return false;
8198 }
8199
8200 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008201 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008202 TAG, "finishExit in " + this
8203 + ": exiting=" + mExiting
8204 + " remove=" + mRemoveOnExit
8205 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07008206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008207 final int N = mChildWindows.size();
8208 for (int i=0; i<N; i++) {
8209 ((WindowState)mChildWindows.get(i)).finishExit();
8210 }
Romain Guy06882f82009-06-10 13:36:04 -07008211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212 if (!mExiting) {
8213 return;
8214 }
Romain Guy06882f82009-06-10 13:36:04 -07008215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 if (isWindowAnimating()) {
8217 return;
8218 }
8219
Joe Onorato8a9b2202010-02-26 18:56:32 -08008220 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008221 TAG, "Exit animation finished in " + this
8222 + ": remove=" + mRemoveOnExit);
8223 if (mSurface != null) {
8224 mDestroySurface.add(this);
8225 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008226 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008227 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 try {
8229 mSurface.hide();
8230 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008231 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232 }
8233 mLastHidden = true;
8234 mKeyWaiter.releasePendingPointerLocked(mSession);
8235 }
8236 mExiting = false;
8237 if (mRemoveOnExit) {
8238 mPendingRemove.add(this);
8239 mRemoveOnExit = false;
8240 }
8241 }
Romain Guy06882f82009-06-10 13:36:04 -07008242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008243 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
8244 if (dsdx < .99999f || dsdx > 1.00001f) return false;
8245 if (dtdy < .99999f || dtdy > 1.00001f) return false;
8246 if (dtdx < -.000001f || dtdx > .000001f) return false;
8247 if (dsdy < -.000001f || dsdy > .000001f) return false;
8248 return true;
8249 }
Romain Guy06882f82009-06-10 13:36:04 -07008250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008251 void computeShownFrameLocked() {
8252 final boolean selfTransformation = mHasLocalTransformation;
8253 Transformation attachedTransformation =
8254 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
8255 ? mAttachedWindow.mTransformation : null;
8256 Transformation appTransformation =
8257 (mAppToken != null && mAppToken.hasTransformation)
8258 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008259
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008260 // Wallpapers are animated based on the "real" window they
8261 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008262 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008263 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07008264 if (mWallpaperTarget.mHasLocalTransformation &&
8265 mWallpaperTarget.mAnimation != null &&
8266 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008267 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008268 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008269 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008270 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008271 }
8272 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07008273 mWallpaperTarget.mAppToken.hasTransformation &&
8274 mWallpaperTarget.mAppToken.animation != null &&
8275 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008276 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008277 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008278 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008279 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008280 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008281 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 if (selfTransformation || attachedTransformation != null
8284 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07008285 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008286 final Rect frame = mFrame;
8287 final float tmpFloats[] = mTmpFloats;
8288 final Matrix tmpMatrix = mTmpMatrix;
8289
8290 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07008291 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008292 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008293 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008294 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07008295 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008297 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 }
8299 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008300 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301 }
8302
8303 // "convert" it into SurfaceFlinger's format
8304 // (a 2x2 matrix + an offset)
8305 // Here we must not transform the position of the surface
8306 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008307 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07008308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 tmpMatrix.getValues(tmpFloats);
8310 mDsDx = tmpFloats[Matrix.MSCALE_X];
8311 mDtDx = tmpFloats[Matrix.MSKEW_X];
8312 mDsDy = tmpFloats[Matrix.MSKEW_Y];
8313 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008314 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
8315 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008316 int w = frame.width();
8317 int h = frame.height();
8318 mShownFrame.set(x, y, x+w, y+h);
8319
8320 // Now set the alpha... but because our current hardware
8321 // can't do alpha transformation on a non-opaque surface,
8322 // turn it off if we are running an animation that is also
8323 // transforming since it is more important to have that
8324 // animation be smooth.
8325 mShownAlpha = mAlpha;
8326 if (!mLimitedAlphaCompositing
8327 || (!PixelFormat.formatHasAlpha(mAttrs.format)
8328 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
8329 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008330 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008331 if (selfTransformation) {
8332 mShownAlpha *= mTransformation.getAlpha();
8333 }
8334 if (attachedTransformation != null) {
8335 mShownAlpha *= attachedTransformation.getAlpha();
8336 }
8337 if (appTransformation != null) {
8338 mShownAlpha *= appTransformation.getAlpha();
8339 }
8340 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008341 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008342 }
Romain Guy06882f82009-06-10 13:36:04 -07008343
Joe Onorato8a9b2202010-02-26 18:56:32 -08008344 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008345 TAG, "Continuing animation in " + this +
8346 ": " + mShownFrame +
8347 ", alpha=" + mTransformation.getAlpha());
8348 return;
8349 }
Romain Guy06882f82009-06-10 13:36:04 -07008350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008351 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008352 if (mXOffset != 0 || mYOffset != 0) {
8353 mShownFrame.offset(mXOffset, mYOffset);
8354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 mShownAlpha = mAlpha;
8356 mDsDx = 1;
8357 mDtDx = 0;
8358 mDsDy = 0;
8359 mDtDy = 1;
8360 }
Romain Guy06882f82009-06-10 13:36:04 -07008361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 /**
8363 * Is this window visible? It is not visible if there is no
8364 * surface, or we are in the process of running an exit animation
8365 * that will remove the surface, or its app token has been hidden.
8366 */
8367 public boolean isVisibleLw() {
8368 final AppWindowToken atoken = mAppToken;
8369 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8370 && (atoken == null || !atoken.hiddenRequested)
8371 && !mExiting && !mDestroying;
8372 }
8373
8374 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008375 * Like {@link #isVisibleLw}, but also counts a window that is currently
8376 * "hidden" behind the keyguard as visible. This allows us to apply
8377 * things like window flags that impact the keyguard.
8378 * XXX I am starting to think we need to have ANOTHER visibility flag
8379 * for this "hidden behind keyguard" state rather than overloading
8380 * mPolicyVisibility. Ungh.
8381 */
8382 public boolean isVisibleOrBehindKeyguardLw() {
8383 final AppWindowToken atoken = mAppToken;
8384 return mSurface != null && !mAttachedHidden
8385 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackborn5943c202010-04-12 21:36:49 -07008386 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending))
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008387 && !mExiting && !mDestroying;
8388 }
8389
8390 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 * Is this window visible, ignoring its app token? It is not visible
8392 * if there is no surface, or we are in the process of running an exit animation
8393 * that will remove the surface.
8394 */
8395 public boolean isWinVisibleLw() {
8396 final AppWindowToken atoken = mAppToken;
8397 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8398 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
8399 && !mExiting && !mDestroying;
8400 }
8401
8402 /**
8403 * The same as isVisible(), but follows the current hidden state of
8404 * the associated app token, not the pending requested hidden state.
8405 */
8406 boolean isVisibleNow() {
8407 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07008408 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008409 }
8410
8411 /**
8412 * Same as isVisible(), but we also count it as visible between the
8413 * call to IWindowSession.add() and the first relayout().
8414 */
8415 boolean isVisibleOrAdding() {
8416 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008417 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
8419 && mPolicyVisibility && !mAttachedHidden
8420 && (atoken == null || !atoken.hiddenRequested)
8421 && !mExiting && !mDestroying;
8422 }
8423
8424 /**
8425 * Is this window currently on-screen? It is on-screen either if it
8426 * is visible or it is currently running an animation before no longer
8427 * being visible.
8428 */
8429 boolean isOnScreen() {
8430 final AppWindowToken atoken = mAppToken;
8431 if (atoken != null) {
8432 return mSurface != null && mPolicyVisibility && !mDestroying
8433 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008434 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008435 } else {
8436 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008437 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 }
8439 }
Romain Guy06882f82009-06-10 13:36:04 -07008440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008441 /**
8442 * Like isOnScreen(), but we don't return true if the window is part
8443 * of a transition that has not yet been started.
8444 */
8445 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008446 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008447 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008448 return false;
8449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008450 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008451 final boolean animating = atoken != null
8452 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008454 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8455 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008456 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 }
8458
8459 /** Is the window or its container currently animating? */
8460 boolean isAnimating() {
8461 final WindowState attached = mAttachedWindow;
8462 final AppWindowToken atoken = mAppToken;
8463 return mAnimation != null
8464 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008465 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 (atoken.animation != null
8467 || atoken.inPendingTransaction));
8468 }
8469
8470 /** Is this window currently animating? */
8471 boolean isWindowAnimating() {
8472 return mAnimation != null;
8473 }
8474
8475 /**
8476 * Like isOnScreen, but returns false if the surface hasn't yet
8477 * been drawn.
8478 */
8479 public boolean isDisplayedLw() {
8480 final AppWindowToken atoken = mAppToken;
8481 return mSurface != null && mPolicyVisibility && !mDestroying
8482 && !mDrawPending && !mCommitDrawPending
8483 && ((!mAttachedHidden &&
8484 (atoken == null || !atoken.hiddenRequested))
8485 || mAnimating);
8486 }
8487
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008488 /**
8489 * Returns true if the window has a surface that it has drawn a
Dianne Hackborn5943c202010-04-12 21:36:49 -07008490 * complete UI in to. Note that this returns true if the orientation
8491 * is changing even if the window hasn't redrawn because we don't want
8492 * to stop things from executing during that time.
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008493 */
8494 public boolean isDrawnLw() {
8495 final AppWindowToken atoken = mAppToken;
8496 return mSurface != null && !mDestroying
Dianne Hackborn5943c202010-04-12 21:36:49 -07008497 && (mOrientationChanging || (!mDrawPending && !mCommitDrawPending));
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008498 }
8499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 public boolean fillsScreenLw(int screenWidth, int screenHeight,
8501 boolean shownFrame, boolean onlyOpaque) {
8502 if (mSurface == null) {
8503 return false;
8504 }
8505 if (mAppToken != null && !mAppToken.appFullscreen) {
8506 return false;
8507 }
8508 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
8509 return false;
8510 }
8511 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008512
8513 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
8514 return frame.left <= mCompatibleScreenFrame.left &&
8515 frame.top <= mCompatibleScreenFrame.top &&
8516 frame.right >= mCompatibleScreenFrame.right &&
8517 frame.bottom >= mCompatibleScreenFrame.bottom;
8518 } else {
8519 return frame.left <= 0 && frame.top <= 0
8520 && frame.right >= screenWidth
8521 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 }
Romain Guy06882f82009-06-10 13:36:04 -07008524
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008525 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008526 * Return true if the window is opaque and fully drawn. This indicates
8527 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008528 */
8529 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008530 return (mAttrs.format == PixelFormat.OPAQUE
8531 || mAttrs.type == TYPE_WALLPAPER)
8532 && mSurface != null && mAnimation == null
8533 && (mAppToken == null || mAppToken.animation == null)
8534 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008535 }
8536
8537 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8538 return
8539 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008540 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8541 // only if it's visible
8542 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008543 // and only if the application fills the compatible screen
8544 mFrame.left <= mCompatibleScreenFrame.left &&
8545 mFrame.top <= mCompatibleScreenFrame.top &&
8546 mFrame.right >= mCompatibleScreenFrame.right &&
8547 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008548 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008549 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008550 }
8551
8552 boolean isFullscreen(int screenWidth, int screenHeight) {
8553 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008554 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 }
8556
8557 void removeLocked() {
8558 if (mAttachedWindow != null) {
8559 mAttachedWindow.mChildWindows.remove(this);
8560 }
8561 destroySurfaceLocked();
8562 mSession.windowRemovedLocked();
8563 try {
8564 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8565 } catch (RuntimeException e) {
8566 // Ignore if it has already been removed (usually because
8567 // we are doing this as part of processing a death note.)
8568 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008569
8570 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8571 if (mInputChannel != null) {
8572 mInputManager.unregisterInputChannel(mInputChannel);
8573
8574 mInputChannel.dispose();
8575 mInputChannel = null;
8576 }
8577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 }
8579
8580 private class DeathRecipient implements IBinder.DeathRecipient {
8581 public void binderDied() {
8582 try {
8583 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008584 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008585 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 if (win != null) {
8587 removeWindowLocked(mSession, win);
8588 }
8589 }
8590 } catch (IllegalArgumentException ex) {
8591 // This will happen if the window has already been
8592 // removed.
8593 }
8594 }
8595 }
8596
8597 /** Returns true if this window desires key events. */
8598 public final boolean canReceiveKeys() {
8599 return isVisibleOrAdding()
8600 && (mViewVisibility == View.VISIBLE)
8601 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8602 }
8603
8604 public boolean hasDrawnLw() {
8605 return mHasDrawn;
8606 }
8607
8608 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008609 return showLw(doAnimation, true);
8610 }
8611
8612 boolean showLw(boolean doAnimation, boolean requestAnim) {
8613 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8614 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008616 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008617 if (doAnimation) {
8618 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8619 + mPolicyVisibility + " mAnimation=" + mAnimation);
8620 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8621 doAnimation = false;
8622 } else if (mPolicyVisibility && mAnimation == null) {
8623 // Check for the case where we are currently visible and
8624 // not animating; we do not want to do animation at such a
8625 // point to become visible when we already are.
8626 doAnimation = false;
8627 }
8628 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008629 mPolicyVisibility = true;
8630 mPolicyVisibilityAfterAnim = true;
8631 if (doAnimation) {
8632 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8633 }
8634 if (requestAnim) {
8635 requestAnimationLocked(0);
8636 }
8637 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
8639
8640 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008641 return hideLw(doAnimation, true);
8642 }
8643
8644 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008645 if (doAnimation) {
8646 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8647 doAnimation = false;
8648 }
8649 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008650 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8651 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008652 if (!current) {
8653 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008654 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008655 if (doAnimation) {
8656 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8657 if (mAnimation == null) {
8658 doAnimation = false;
8659 }
8660 }
8661 if (doAnimation) {
8662 mPolicyVisibilityAfterAnim = false;
8663 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008664 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008665 mPolicyVisibilityAfterAnim = false;
8666 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008667 // Window is no longer visible -- make sure if we were waiting
8668 // for it to be displayed before enabling the display, that
8669 // we allow the display to be enabled now.
8670 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008671 if (mCurrentFocus == this) {
8672 mFocusMayChange = true;
8673 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008674 }
8675 if (requestAnim) {
8676 requestAnimationLocked(0);
8677 }
8678 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679 }
8680
8681 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008682 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8683 pw.print(" mClient="); pw.println(mClient.asBinder());
8684 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8685 if (mAttachedWindow != null || mLayoutAttached) {
8686 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8687 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8688 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008689 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8690 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8691 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008692 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8693 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008694 }
8695 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8696 pw.print(" mSubLayer="); pw.print(mSubLayer);
8697 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8698 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8699 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8700 pw.print("="); pw.print(mAnimLayer);
8701 pw.print(" mLastLayer="); pw.println(mLastLayer);
8702 if (mSurface != null) {
8703 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008704 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8705 pw.print(" layer="); pw.print(mSurfaceLayer);
8706 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8707 pw.print(" rect=("); pw.print(mSurfaceX);
8708 pw.print(","); pw.print(mSurfaceY);
8709 pw.print(") "); pw.print(mSurfaceW);
8710 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008711 }
8712 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8713 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8714 if (mAppToken != null) {
8715 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8716 }
8717 if (mTargetAppToken != null) {
8718 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8719 }
8720 pw.print(prefix); pw.print("mViewVisibility=0x");
8721 pw.print(Integer.toHexString(mViewVisibility));
8722 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008723 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8724 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008725 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8726 pw.print(prefix); pw.print("mPolicyVisibility=");
8727 pw.print(mPolicyVisibility);
8728 pw.print(" mPolicyVisibilityAfterAnim=");
8729 pw.print(mPolicyVisibilityAfterAnim);
8730 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8731 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008732 if (!mRelayoutCalled) {
8733 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8734 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008735 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008736 pw.print(" h="); pw.print(mRequestedHeight);
8737 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008738 if (mXOffset != 0 || mYOffset != 0) {
8739 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8740 pw.print(" y="); pw.println(mYOffset);
8741 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008742 pw.print(prefix); pw.print("mGivenContentInsets=");
8743 mGivenContentInsets.printShortString(pw);
8744 pw.print(" mGivenVisibleInsets=");
8745 mGivenVisibleInsets.printShortString(pw);
8746 pw.println();
8747 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8748 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8749 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8750 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008751 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008752 pw.print(prefix); pw.print("mShownFrame=");
8753 mShownFrame.printShortString(pw);
8754 pw.print(" last="); mLastShownFrame.printShortString(pw);
8755 pw.println();
8756 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8757 pw.print(" last="); mLastFrame.printShortString(pw);
8758 pw.println();
8759 pw.print(prefix); pw.print("mContainingFrame=");
8760 mContainingFrame.printShortString(pw);
8761 pw.print(" mDisplayFrame=");
8762 mDisplayFrame.printShortString(pw);
8763 pw.println();
8764 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8765 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8766 pw.println();
8767 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8768 pw.print(" last="); mLastContentInsets.printShortString(pw);
8769 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8770 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8771 pw.println();
8772 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8773 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8774 pw.print(" mAlpha="); pw.print(mAlpha);
8775 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8776 }
8777 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8778 || mAnimation != null) {
8779 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8780 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8781 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8782 pw.print(" mAnimation="); pw.println(mAnimation);
8783 }
8784 if (mHasTransformation || mHasLocalTransformation) {
8785 pw.print(prefix); pw.print("XForm: has=");
8786 pw.print(mHasTransformation);
8787 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8788 pw.print(" "); mTransformation.printShortString(pw);
8789 pw.println();
8790 }
8791 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8792 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8793 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8794 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8795 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8796 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8797 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8798 pw.print(" mDestroying="); pw.print(mDestroying);
8799 pw.print(" mRemoved="); pw.println(mRemoved);
8800 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008801 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008802 pw.print(prefix); pw.print("mOrientationChanging=");
8803 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008804 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8805 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008806 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008807 if (mHScale != 1 || mVScale != 1) {
8808 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8809 pw.print(" mVScale="); pw.println(mVScale);
8810 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008811 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008812 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8813 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8814 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008815 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8816 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8817 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008819 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008820
8821 String makeInputChannelName() {
8822 return Integer.toHexString(System.identityHashCode(this))
8823 + " " + mAttrs.getTitle();
8824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008825
8826 @Override
8827 public String toString() {
8828 return "Window{"
8829 + Integer.toHexString(System.identityHashCode(this))
8830 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
8831 }
8832 }
Romain Guy06882f82009-06-10 13:36:04 -07008833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008834 // -------------------------------------------------------------
8835 // Window Token State
8836 // -------------------------------------------------------------
8837
8838 class WindowToken {
8839 // The actual token.
8840 final IBinder token;
8841
8842 // The type of window this token is for, as per WindowManager.LayoutParams.
8843 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 // Set if this token was explicitly added by a client, so should
8846 // not be removed when all windows are removed.
8847 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008848
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008849 // For printing.
8850 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852 // If this is an AppWindowToken, this is non-null.
8853 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008855 // All of the windows associated with this token.
8856 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8857
8858 // Is key dispatching paused for this token?
8859 boolean paused = false;
8860
8861 // Should this token's windows be hidden?
8862 boolean hidden;
8863
8864 // Temporary for finding which tokens no longer have visible windows.
8865 boolean hasVisible;
8866
Dianne Hackborna8f60182009-09-01 19:01:50 -07008867 // Set to true when this token is in a pending transaction where it
8868 // will be shown.
8869 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008870
Dianne Hackborna8f60182009-09-01 19:01:50 -07008871 // Set to true when this token is in a pending transaction where it
8872 // will be hidden.
8873 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008874
Dianne Hackborna8f60182009-09-01 19:01:50 -07008875 // Set to true when this token is in a pending transaction where its
8876 // windows will be put to the bottom of the list.
8877 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008878
Dianne Hackborna8f60182009-09-01 19:01:50 -07008879 // Set to true when this token is in a pending transaction where its
8880 // windows will be put to the top of the list.
8881 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 WindowToken(IBinder _token, int type, boolean _explicit) {
8884 token = _token;
8885 windowType = type;
8886 explicit = _explicit;
8887 }
8888
8889 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008890 pw.print(prefix); pw.print("token="); pw.println(token);
8891 pw.print(prefix); pw.print("windows="); pw.println(windows);
8892 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8893 pw.print(" hidden="); pw.print(hidden);
8894 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008895 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8896 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8897 pw.print(" waitingToHide="); pw.print(waitingToHide);
8898 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8899 pw.print(" sendingToTop="); pw.println(sendingToTop);
8900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008901 }
8902
8903 @Override
8904 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008905 if (stringName == null) {
8906 StringBuilder sb = new StringBuilder();
8907 sb.append("WindowToken{");
8908 sb.append(Integer.toHexString(System.identityHashCode(this)));
8909 sb.append(" token="); sb.append(token); sb.append('}');
8910 stringName = sb.toString();
8911 }
8912 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008913 }
8914 };
8915
8916 class AppWindowToken extends WindowToken {
8917 // Non-null only for application tokens.
8918 final IApplicationToken appToken;
8919
8920 // All of the windows and child windows that are included in this
8921 // application token. Note this list is NOT sorted!
8922 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8923
8924 int groupId = -1;
8925 boolean appFullscreen;
8926 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Romain Guy06882f82009-06-10 13:36:04 -07008927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 // These are used for determining when all windows associated with
8929 // an activity have been drawn, so they can be made visible together
8930 // at the same time.
8931 int lastTransactionSequence = mTransactionSequence-1;
8932 int numInterestingWindows;
8933 int numDrawnWindows;
8934 boolean inPendingTransaction;
8935 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 // Is this token going to be hidden in a little while? If so, it
8938 // won't be taken into account for setting the screen orientation.
8939 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008941 // Is this window's surface needed? This is almost like hidden, except
8942 // it will sometimes be true a little earlier: when the token has
8943 // been shown, but is still waiting for its app transition to execute
8944 // before making its windows shown.
8945 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008947 // Have we told the window clients to hide themselves?
8948 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008950 // Last visibility state we reported to the app token.
8951 boolean reportedVisible;
8952
8953 // Set to true when the token has been removed from the window mgr.
8954 boolean removed;
8955
8956 // Have we been asked to have this token keep the screen frozen?
8957 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008959 boolean animating;
8960 Animation animation;
8961 boolean hasTransformation;
8962 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008964 // Offset to the window of all layers in the token, for use by
8965 // AppWindowToken animations.
8966 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008968 // Information about an application starting window if displayed.
8969 StartingData startingData;
8970 WindowState startingWindow;
8971 View startingView;
8972 boolean startingDisplayed;
8973 boolean startingMoved;
8974 boolean firstWindowDrawn;
8975
8976 AppWindowToken(IApplicationToken _token) {
8977 super(_token.asBinder(),
8978 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8979 appWindowToken = this;
8980 appToken = _token;
8981 }
Romain Guy06882f82009-06-10 13:36:04 -07008982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008983 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008984 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 TAG, "Setting animation in " + this + ": " + anim);
8986 animation = anim;
8987 animating = false;
8988 anim.restrictDuration(MAX_ANIMATION_DURATION);
8989 anim.scaleCurrentDuration(mTransitionAnimationScale);
8990 int zorder = anim.getZAdjustment();
8991 int adj = 0;
8992 if (zorder == Animation.ZORDER_TOP) {
8993 adj = TYPE_LAYER_OFFSET;
8994 } else if (zorder == Animation.ZORDER_BOTTOM) {
8995 adj = -TYPE_LAYER_OFFSET;
8996 }
Romain Guy06882f82009-06-10 13:36:04 -07008997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 if (animLayerAdjustment != adj) {
8999 animLayerAdjustment = adj;
9000 updateLayers();
9001 }
9002 }
Romain Guy06882f82009-06-10 13:36:04 -07009003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009004 public void setDummyAnimation() {
9005 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009006 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 TAG, "Setting dummy animation in " + this);
9008 animation = sDummyAnimation;
9009 }
9010 }
9011
9012 public void clearAnimation() {
9013 if (animation != null) {
9014 animation = null;
9015 animating = true;
9016 }
9017 }
Romain Guy06882f82009-06-10 13:36:04 -07009018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 void updateLayers() {
9020 final int N = allAppWindows.size();
9021 final int adj = animLayerAdjustment;
9022 for (int i=0; i<N; i++) {
9023 WindowState w = allAppWindows.get(i);
9024 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009025 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009026 + w.mAnimLayer);
9027 if (w == mInputMethodTarget) {
9028 setInputMethodAnimLayerAdjustment(adj);
9029 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009030 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07009031 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009033 }
9034 }
Romain Guy06882f82009-06-10 13:36:04 -07009035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009036 void sendAppVisibilityToClients() {
9037 final int N = allAppWindows.size();
9038 for (int i=0; i<N; i++) {
9039 WindowState win = allAppWindows.get(i);
9040 if (win == startingWindow && clientHidden) {
9041 // Don't hide the starting window.
9042 continue;
9043 }
9044 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009045 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009046 "Setting visibility of " + win + ": " + (!clientHidden));
9047 win.mClient.dispatchAppVisibility(!clientHidden);
9048 } catch (RemoteException e) {
9049 }
9050 }
9051 }
Romain Guy06882f82009-06-10 13:36:04 -07009052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009053 void showAllWindowsLocked() {
9054 final int NW = allAppWindows.size();
9055 for (int i=0; i<NW; i++) {
9056 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009057 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009058 "performing show on: " + w);
9059 w.performShowLocked();
9060 }
9061 }
Romain Guy06882f82009-06-10 13:36:04 -07009062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009063 // This must be called while inside a transaction.
9064 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009065 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009066 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07009067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009068 if (animation == sDummyAnimation) {
9069 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009070 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009071 // when it is really time to animate, this will be set to
9072 // a real animation and the next call will execute normally.
9073 return false;
9074 }
Romain Guy06882f82009-06-10 13:36:04 -07009075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009076 if ((allDrawn || animating || startingDisplayed) && animation != null) {
9077 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009078 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 TAG, "Starting animation in " + this +
9080 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
9081 + " scale=" + mTransitionAnimationScale
9082 + " allDrawn=" + allDrawn + " animating=" + animating);
9083 animation.initialize(dw, dh, dw, dh);
9084 animation.setStartTime(currentTime);
9085 animating = true;
9086 }
9087 transformation.clear();
9088 final boolean more = animation.getTransformation(
9089 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009090 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009091 TAG, "Stepped animation in " + this +
9092 ": more=" + more + ", xform=" + transformation);
9093 if (more) {
9094 // we're done!
9095 hasTransformation = true;
9096 return true;
9097 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009098 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 TAG, "Finished animation in " + this +
9100 " @ " + currentTime);
9101 animation = null;
9102 }
9103 } else if (animation != null) {
9104 // If the display is frozen, and there is a pending animation,
9105 // clear it and make sure we run the cleanup code.
9106 animating = true;
9107 animation = null;
9108 }
9109
9110 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07009111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009112 if (!animating) {
9113 return false;
9114 }
9115
9116 clearAnimation();
9117 animating = false;
9118 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
9119 moveInputMethodWindowsIfNeededLocked(true);
9120 }
Romain Guy06882f82009-06-10 13:36:04 -07009121
Joe Onorato8a9b2202010-02-26 18:56:32 -08009122 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009123 TAG, "Animation done in " + this
9124 + ": reportedVisible=" + reportedVisible);
9125
9126 transformation.clear();
9127 if (animLayerAdjustment != 0) {
9128 animLayerAdjustment = 0;
9129 updateLayers();
9130 }
Romain Guy06882f82009-06-10 13:36:04 -07009131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009132 final int N = windows.size();
9133 for (int i=0; i<N; i++) {
9134 ((WindowState)windows.get(i)).finishExit();
9135 }
9136 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07009137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009138 return false;
9139 }
9140
9141 void updateReportedVisibilityLocked() {
9142 if (appToken == null) {
9143 return;
9144 }
Romain Guy06882f82009-06-10 13:36:04 -07009145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 int numInteresting = 0;
9147 int numVisible = 0;
9148 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07009149
Joe Onorato8a9b2202010-02-26 18:56:32 -08009150 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009151 final int N = allAppWindows.size();
9152 for (int i=0; i<N; i++) {
9153 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08009154 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07009155 || win.mViewVisibility != View.VISIBLE
9156 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009157 continue;
9158 }
9159 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009160 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009161 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009162 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009163 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009164 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 + " pv=" + win.mPolicyVisibility
9166 + " dp=" + win.mDrawPending
9167 + " cdp=" + win.mCommitDrawPending
9168 + " ah=" + win.mAttachedHidden
9169 + " th="
9170 + (win.mAppToken != null
9171 ? win.mAppToken.hiddenRequested : false)
9172 + " a=" + win.mAnimating);
9173 }
9174 }
9175 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009176 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177 if (!win.isAnimating()) {
9178 numVisible++;
9179 }
9180 nowGone = false;
9181 } else if (win.isAnimating()) {
9182 nowGone = false;
9183 }
9184 }
Romain Guy06882f82009-06-10 13:36:04 -07009185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009186 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009187 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009188 + numInteresting + " visible=" + numVisible);
9189 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009190 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009191 TAG, "Visibility changed in " + this
9192 + ": vis=" + nowVisible);
9193 reportedVisible = nowVisible;
9194 Message m = mH.obtainMessage(
9195 H.REPORT_APPLICATION_TOKEN_WINDOWS,
9196 nowVisible ? 1 : 0,
9197 nowGone ? 1 : 0,
9198 this);
9199 mH.sendMessage(m);
9200 }
9201 }
Romain Guy06882f82009-06-10 13:36:04 -07009202
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009203 WindowState findMainWindow() {
9204 int j = windows.size();
9205 while (j > 0) {
9206 j--;
9207 WindowState win = windows.get(j);
9208 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
9209 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
9210 return win;
9211 }
9212 }
9213 return null;
9214 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009216 void dump(PrintWriter pw, String prefix) {
9217 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009218 if (appToken != null) {
9219 pw.print(prefix); pw.println("app=true");
9220 }
9221 if (allAppWindows.size() > 0) {
9222 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
9223 }
9224 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009225 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009226 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
9227 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
9228 pw.print(" clientHidden="); pw.print(clientHidden);
9229 pw.print(" willBeHidden="); pw.print(willBeHidden);
9230 pw.print(" reportedVisible="); pw.println(reportedVisible);
9231 if (paused || freezingScreen) {
9232 pw.print(prefix); pw.print("paused="); pw.print(paused);
9233 pw.print(" freezingScreen="); pw.println(freezingScreen);
9234 }
9235 if (numInterestingWindows != 0 || numDrawnWindows != 0
9236 || inPendingTransaction || allDrawn) {
9237 pw.print(prefix); pw.print("numInterestingWindows=");
9238 pw.print(numInterestingWindows);
9239 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
9240 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
9241 pw.print(" allDrawn="); pw.println(allDrawn);
9242 }
9243 if (animating || animation != null) {
9244 pw.print(prefix); pw.print("animating="); pw.print(animating);
9245 pw.print(" animation="); pw.println(animation);
9246 }
9247 if (animLayerAdjustment != 0) {
9248 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
9249 }
9250 if (hasTransformation) {
9251 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
9252 pw.print(" transformation="); transformation.printShortString(pw);
9253 pw.println();
9254 }
9255 if (startingData != null || removed || firstWindowDrawn) {
9256 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
9257 pw.print(" removed="); pw.print(removed);
9258 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
9259 }
9260 if (startingWindow != null || startingView != null
9261 || startingDisplayed || startingMoved) {
9262 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
9263 pw.print(" startingView="); pw.print(startingView);
9264 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
9265 pw.print(" startingMoved"); pw.println(startingMoved);
9266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009267 }
9268
9269 @Override
9270 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009271 if (stringName == null) {
9272 StringBuilder sb = new StringBuilder();
9273 sb.append("AppWindowToken{");
9274 sb.append(Integer.toHexString(System.identityHashCode(this)));
9275 sb.append(" token="); sb.append(token); sb.append('}');
9276 stringName = sb.toString();
9277 }
9278 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009279 }
9280 }
Romain Guy06882f82009-06-10 13:36:04 -07009281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 // -------------------------------------------------------------
9283 // DummyAnimation
9284 // -------------------------------------------------------------
9285
9286 // This is an animation that does nothing: it just immediately finishes
9287 // itself every time it is called. It is used as a stub animation in cases
9288 // where we want to synchronize multiple things that may be animating.
9289 static final class DummyAnimation extends Animation {
9290 public boolean getTransformation(long currentTime, Transformation outTransformation) {
9291 return false;
9292 }
9293 }
9294 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07009295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009296 // -------------------------------------------------------------
9297 // Async Handler
9298 // -------------------------------------------------------------
9299
9300 static final class StartingData {
9301 final String pkg;
9302 final int theme;
9303 final CharSequence nonLocalizedLabel;
9304 final int labelRes;
9305 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07009306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
9308 int _labelRes, int _icon) {
9309 pkg = _pkg;
9310 theme = _theme;
9311 nonLocalizedLabel = _nonLocalizedLabel;
9312 labelRes = _labelRes;
9313 icon = _icon;
9314 }
9315 }
9316
9317 private final class H extends Handler {
9318 public static final int REPORT_FOCUS_CHANGE = 2;
9319 public static final int REPORT_LOSING_FOCUS = 3;
9320 public static final int ANIMATE = 4;
9321 public static final int ADD_STARTING = 5;
9322 public static final int REMOVE_STARTING = 6;
9323 public static final int FINISHED_STARTING = 7;
9324 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 public static final int WINDOW_FREEZE_TIMEOUT = 11;
9326 public static final int HOLD_SCREEN_CHANGED = 12;
9327 public static final int APP_TRANSITION_TIMEOUT = 13;
9328 public static final int PERSIST_ANIMATION_SCALE = 14;
9329 public static final int FORCE_GC = 15;
9330 public static final int ENABLE_SCREEN = 16;
9331 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009332 public static final int SEND_NEW_CONFIGURATION = 18;
Romain Guy06882f82009-06-10 13:36:04 -07009333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009334 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07009335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 public H() {
9337 }
Romain Guy06882f82009-06-10 13:36:04 -07009338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009339 @Override
9340 public void handleMessage(Message msg) {
9341 switch (msg.what) {
9342 case REPORT_FOCUS_CHANGE: {
9343 WindowState lastFocus;
9344 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07009345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 synchronized(mWindowMap) {
9347 lastFocus = mLastFocus;
9348 newFocus = mCurrentFocus;
9349 if (lastFocus == newFocus) {
9350 // Focus is not changing, so nothing to do.
9351 return;
9352 }
9353 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009354 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 // + " to " + newFocus);
9356 if (newFocus != null && lastFocus != null
9357 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009358 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009359 mLosingFocus.add(lastFocus);
9360 lastFocus = null;
9361 }
9362 }
9363
9364 if (lastFocus != newFocus) {
9365 //System.out.println("Changing focus from " + lastFocus
9366 // + " to " + newFocus);
9367 if (newFocus != null) {
9368 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009369 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009370 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
9371 } catch (RemoteException e) {
9372 // Ignore if process has died.
9373 }
9374 }
9375
9376 if (lastFocus != null) {
9377 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009378 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009379 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
9380 } catch (RemoteException e) {
9381 // Ignore if process has died.
9382 }
9383 }
9384 }
9385 } break;
9386
9387 case REPORT_LOSING_FOCUS: {
9388 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07009389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009390 synchronized(mWindowMap) {
9391 losers = mLosingFocus;
9392 mLosingFocus = new ArrayList<WindowState>();
9393 }
9394
9395 final int N = losers.size();
9396 for (int i=0; i<N; i++) {
9397 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009398 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009399 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
9400 } catch (RemoteException e) {
9401 // Ignore if process has died.
9402 }
9403 }
9404 } break;
9405
9406 case ANIMATE: {
9407 synchronized(mWindowMap) {
9408 mAnimationPending = false;
9409 performLayoutAndPlaceSurfacesLocked();
9410 }
9411 } break;
9412
9413 case ADD_STARTING: {
9414 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9415 final StartingData sd = wtoken.startingData;
9416
9417 if (sd == null) {
9418 // Animation has been canceled... do nothing.
9419 return;
9420 }
Romain Guy06882f82009-06-10 13:36:04 -07009421
Joe Onorato8a9b2202010-02-26 18:56:32 -08009422 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009423 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07009424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 View view = null;
9426 try {
9427 view = mPolicy.addStartingWindow(
9428 wtoken.token, sd.pkg,
9429 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
9430 sd.icon);
9431 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009432 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009433 }
9434
9435 if (view != null) {
9436 boolean abort = false;
9437
9438 synchronized(mWindowMap) {
9439 if (wtoken.removed || wtoken.startingData == null) {
9440 // If the window was successfully added, then
9441 // we need to remove it.
9442 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009443 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009444 "Aborted starting " + wtoken
9445 + ": removed=" + wtoken.removed
9446 + " startingData=" + wtoken.startingData);
9447 wtoken.startingWindow = null;
9448 wtoken.startingData = null;
9449 abort = true;
9450 }
9451 } else {
9452 wtoken.startingView = view;
9453 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009454 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009455 "Added starting " + wtoken
9456 + ": startingWindow="
9457 + wtoken.startingWindow + " startingView="
9458 + wtoken.startingView);
9459 }
9460
9461 if (abort) {
9462 try {
9463 mPolicy.removeStartingWindow(wtoken.token, view);
9464 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009465 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009466 }
9467 }
9468 }
9469 } break;
9470
9471 case REMOVE_STARTING: {
9472 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9473 IBinder token = null;
9474 View view = null;
9475 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009476 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477 + wtoken + ": startingWindow="
9478 + wtoken.startingWindow + " startingView="
9479 + wtoken.startingView);
9480 if (wtoken.startingWindow != null) {
9481 view = wtoken.startingView;
9482 token = wtoken.token;
9483 wtoken.startingData = null;
9484 wtoken.startingView = null;
9485 wtoken.startingWindow = null;
9486 }
9487 }
9488 if (view != null) {
9489 try {
9490 mPolicy.removeStartingWindow(token, view);
9491 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009492 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009493 }
9494 }
9495 } break;
9496
9497 case FINISHED_STARTING: {
9498 IBinder token = null;
9499 View view = null;
9500 while (true) {
9501 synchronized (mWindowMap) {
9502 final int N = mFinishedStarting.size();
9503 if (N <= 0) {
9504 break;
9505 }
9506 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9507
Joe Onorato8a9b2202010-02-26 18:56:32 -08009508 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 "Finished starting " + wtoken
9510 + ": startingWindow=" + wtoken.startingWindow
9511 + " startingView=" + wtoken.startingView);
9512
9513 if (wtoken.startingWindow == null) {
9514 continue;
9515 }
9516
9517 view = wtoken.startingView;
9518 token = wtoken.token;
9519 wtoken.startingData = null;
9520 wtoken.startingView = null;
9521 wtoken.startingWindow = null;
9522 }
9523
9524 try {
9525 mPolicy.removeStartingWindow(token, view);
9526 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009527 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009528 }
9529 }
9530 } break;
9531
9532 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9533 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9534
9535 boolean nowVisible = msg.arg1 != 0;
9536 boolean nowGone = msg.arg2 != 0;
9537
9538 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009539 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009540 TAG, "Reporting visible in " + wtoken
9541 + " visible=" + nowVisible
9542 + " gone=" + nowGone);
9543 if (nowVisible) {
9544 wtoken.appToken.windowsVisible();
9545 } else {
9546 wtoken.appToken.windowsGone();
9547 }
9548 } catch (RemoteException ex) {
9549 }
9550 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552 case WINDOW_FREEZE_TIMEOUT: {
9553 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009554 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 int i = mWindows.size();
9556 while (i > 0) {
9557 i--;
9558 WindowState w = (WindowState)mWindows.get(i);
9559 if (w.mOrientationChanging) {
9560 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009561 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009562 }
9563 }
9564 performLayoutAndPlaceSurfacesLocked();
9565 }
9566 break;
9567 }
Romain Guy06882f82009-06-10 13:36:04 -07009568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009569 case HOLD_SCREEN_CHANGED: {
9570 Session oldHold;
9571 Session newHold;
9572 synchronized (mWindowMap) {
9573 oldHold = mLastReportedHold;
9574 newHold = (Session)msg.obj;
9575 mLastReportedHold = newHold;
9576 }
Romain Guy06882f82009-06-10 13:36:04 -07009577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578 if (oldHold != newHold) {
9579 try {
9580 if (oldHold != null) {
9581 mBatteryStats.noteStopWakelock(oldHold.mUid,
9582 "window",
9583 BatteryStats.WAKE_TYPE_WINDOW);
9584 }
9585 if (newHold != null) {
9586 mBatteryStats.noteStartWakelock(newHold.mUid,
9587 "window",
9588 BatteryStats.WAKE_TYPE_WINDOW);
9589 }
9590 } catch (RemoteException e) {
9591 }
9592 }
9593 break;
9594 }
Romain Guy06882f82009-06-10 13:36:04 -07009595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009596 case APP_TRANSITION_TIMEOUT: {
9597 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009598 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009599 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009600 "*** APP TRANSITION TIMEOUT");
9601 mAppTransitionReady = true;
9602 mAppTransitionTimeout = true;
9603 performLayoutAndPlaceSurfacesLocked();
9604 }
9605 }
9606 break;
9607 }
Romain Guy06882f82009-06-10 13:36:04 -07009608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009609 case PERSIST_ANIMATION_SCALE: {
9610 Settings.System.putFloat(mContext.getContentResolver(),
9611 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9612 Settings.System.putFloat(mContext.getContentResolver(),
9613 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9614 break;
9615 }
Romain Guy06882f82009-06-10 13:36:04 -07009616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009617 case FORCE_GC: {
9618 synchronized(mWindowMap) {
9619 if (mAnimationPending) {
9620 // If we are animating, don't do the gc now but
9621 // delay a bit so we don't interrupt the animation.
9622 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9623 2000);
9624 return;
9625 }
9626 // If we are currently rotating the display, it will
9627 // schedule a new message when done.
9628 if (mDisplayFrozen) {
9629 return;
9630 }
9631 mFreezeGcPending = 0;
9632 }
9633 Runtime.getRuntime().gc();
9634 break;
9635 }
Romain Guy06882f82009-06-10 13:36:04 -07009636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637 case ENABLE_SCREEN: {
9638 performEnableScreen();
9639 break;
9640 }
Romain Guy06882f82009-06-10 13:36:04 -07009641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009642 case APP_FREEZE_TIMEOUT: {
9643 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009644 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009645 int i = mAppTokens.size();
9646 while (i > 0) {
9647 i--;
9648 AppWindowToken tok = mAppTokens.get(i);
9649 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009650 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009651 unsetAppFreezingScreenLocked(tok, true, true);
9652 }
9653 }
9654 }
9655 break;
9656 }
Romain Guy06882f82009-06-10 13:36:04 -07009657
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009658 case SEND_NEW_CONFIGURATION: {
9659 removeMessages(SEND_NEW_CONFIGURATION);
9660 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009661 break;
9662 }
Romain Guy06882f82009-06-10 13:36:04 -07009663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664 }
9665 }
9666 }
9667
9668 // -------------------------------------------------------------
9669 // IWindowManager API
9670 // -------------------------------------------------------------
9671
9672 public IWindowSession openSession(IInputMethodClient client,
9673 IInputContext inputContext) {
9674 if (client == null) throw new IllegalArgumentException("null client");
9675 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009676 Session session = new Session(client, inputContext);
9677 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009678 }
9679
9680 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9681 synchronized (mWindowMap) {
9682 // The focus for the client is the window immediately below
9683 // where we would place the input method window.
9684 int idx = findDesiredInputMethodWindowIndexLocked(false);
9685 WindowState imFocus;
9686 if (idx > 0) {
9687 imFocus = (WindowState)mWindows.get(idx-1);
9688 if (imFocus != null) {
9689 if (imFocus.mSession.mClient != null &&
9690 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9691 return true;
9692 }
9693 }
9694 }
9695 }
9696 return false;
9697 }
Romain Guy06882f82009-06-10 13:36:04 -07009698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009699 // -------------------------------------------------------------
9700 // Internals
9701 // -------------------------------------------------------------
9702
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009703 final WindowState windowForClientLocked(Session session, IWindow client,
9704 boolean throwOnError) {
9705 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009706 }
Romain Guy06882f82009-06-10 13:36:04 -07009707
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009708 final WindowState windowForClientLocked(Session session, IBinder client,
9709 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009710 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009711 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 TAG, "Looking up client " + client + ": " + win);
9713 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009714 RuntimeException ex = new IllegalArgumentException(
9715 "Requested window " + client + " does not exist");
9716 if (throwOnError) {
9717 throw ex;
9718 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009719 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009720 return null;
9721 }
9722 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009723 RuntimeException ex = new IllegalArgumentException(
9724 "Requested window " + client + " is in session " +
9725 win.mSession + ", not " + session);
9726 if (throwOnError) {
9727 throw ex;
9728 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009729 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009730 return null;
9731 }
9732
9733 return win;
9734 }
9735
Dianne Hackborna8f60182009-09-01 19:01:50 -07009736 final void rebuildAppWindowListLocked() {
9737 int NW = mWindows.size();
9738 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009739 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009740 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009741
Dianne Hackborna8f60182009-09-01 19:01:50 -07009742 // First remove all existing app windows.
9743 i=0;
9744 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009745 WindowState w = (WindowState)mWindows.get(i);
9746 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009747 WindowState win = (WindowState)mWindows.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009748 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009749 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009750 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009751 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009752 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009753 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9754 && lastWallpaper == i-1) {
9755 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009756 }
9757 i++;
9758 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009759
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009760 // The wallpaper window(s) typically live at the bottom of the stack,
9761 // so skip them before adding app tokens.
9762 lastWallpaper++;
9763 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009764
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009765 // First add all of the exiting app tokens... these are no longer
9766 // in the main app list, but still have windows shown. We put them
9767 // in the back because now that the animation is over we no longer
9768 // will care about them.
9769 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009770 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009771 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9772 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009773
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009774 // And add in the still active app tokens in Z order.
9775 NT = mAppTokens.size();
9776 for (int j=0; j<NT; j++) {
9777 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009778 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009779
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009780 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009781 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009782 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009783 + " windows but added " + i);
9784 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009785 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009787 private final void assignLayersLocked() {
9788 int N = mWindows.size();
9789 int curBaseLayer = 0;
9790 int curLayer = 0;
9791 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 for (i=0; i<N; i++) {
9794 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009795 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9796 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 curLayer += WINDOW_LAYER_MULTIPLIER;
9798 w.mLayer = curLayer;
9799 } else {
9800 curBaseLayer = curLayer = w.mBaseLayer;
9801 w.mLayer = curLayer;
9802 }
9803 if (w.mTargetAppToken != null) {
9804 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9805 } else if (w.mAppToken != null) {
9806 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9807 } else {
9808 w.mAnimLayer = w.mLayer;
9809 }
9810 if (w.mIsImWindow) {
9811 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009812 } else if (w.mIsWallpaper) {
9813 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009815 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 + w.mAnimLayer);
9817 //System.out.println(
9818 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9819 }
9820 }
9821
9822 private boolean mInLayout = false;
9823 private final void performLayoutAndPlaceSurfacesLocked() {
9824 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009825 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 throw new RuntimeException("Recursive call!");
9827 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009828 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009829 return;
9830 }
9831
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009832 if (mWaitingForConfig) {
9833 // Our configuration has changed (most likely rotation), but we
9834 // don't yet have the complete configuration to report to
9835 // applications. Don't do any window layout until we have it.
9836 return;
9837 }
9838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009839 boolean recoveringMemory = false;
9840 if (mForceRemoves != null) {
9841 recoveringMemory = true;
9842 // Wait a little it for things to settle down, and off we go.
9843 for (int i=0; i<mForceRemoves.size(); i++) {
9844 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009845 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 removeWindowInnerLocked(ws.mSession, ws);
9847 }
9848 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009849 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009850 Object tmp = new Object();
9851 synchronized (tmp) {
9852 try {
9853 tmp.wait(250);
9854 } catch (InterruptedException e) {
9855 }
9856 }
9857 }
Romain Guy06882f82009-06-10 13:36:04 -07009858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 mInLayout = true;
9860 try {
9861 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 int i = mPendingRemove.size()-1;
9864 if (i >= 0) {
9865 while (i >= 0) {
9866 WindowState w = mPendingRemove.get(i);
9867 removeWindowInnerLocked(w.mSession, w);
9868 i--;
9869 }
9870 mPendingRemove.clear();
9871
9872 mInLayout = false;
9873 assignLayersLocked();
9874 mLayoutNeeded = true;
9875 performLayoutAndPlaceSurfacesLocked();
9876
9877 } else {
9878 mInLayout = false;
9879 if (mLayoutNeeded) {
9880 requestAnimationLocked(0);
9881 }
9882 }
9883 } catch (RuntimeException e) {
9884 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009885 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 }
9887 }
9888
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009889 private final int performLayoutLockedInner() {
9890 if (!mLayoutNeeded) {
9891 return 0;
9892 }
9893
9894 mLayoutNeeded = false;
9895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009896 final int dw = mDisplay.getWidth();
9897 final int dh = mDisplay.getHeight();
9898
9899 final int N = mWindows.size();
9900 int i;
9901
Joe Onorato8a9b2202010-02-26 18:56:32 -08009902 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009903 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9904
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009905 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009906
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009907 int seq = mLayoutSeq+1;
9908 if (seq < 0) seq = 0;
9909 mLayoutSeq = seq;
9910
9911 // First perform layout of any root windows (not attached
9912 // to another window).
9913 int topAttached = -1;
9914 for (i = N-1; i >= 0; i--) {
9915 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009917 // Don't do layout of a window if it is not visible, or
9918 // soon won't be visible, to avoid wasting time and funky
9919 // changes while a window is animating away.
9920 final AppWindowToken atoken = win.mAppToken;
9921 final boolean gone = win.mViewVisibility == View.GONE
9922 || !win.mRelayoutCalled
9923 || win.mRootToken.hidden
9924 || (atoken != null && atoken.hiddenRequested)
9925 || win.mAttachedHidden
9926 || win.mExiting || win.mDestroying;
9927
9928 if (!win.mLayoutAttached) {
9929 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
9930 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9931 + " mLayoutAttached=" + win.mLayoutAttached);
9932 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
9933 + win.mViewVisibility + " mRelayoutCalled="
9934 + win.mRelayoutCalled + " hidden="
9935 + win.mRootToken.hidden + " hiddenRequested="
9936 + (atoken != null && atoken.hiddenRequested)
9937 + " mAttachedHidden=" + win.mAttachedHidden);
9938 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009939
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009940 // If this view is GONE, then skip it -- keep the current
9941 // frame, and let the caller know so they can ignore it
9942 // if they want. (We do the normal layout for INVISIBLE
9943 // windows, since that means "perform layout as normal,
9944 // just don't display").
9945 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009946 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009947 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9948 win.mLayoutSeq = seq;
9949 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9950 + win.mFrame + " mContainingFrame="
9951 + win.mContainingFrame + " mDisplayFrame="
9952 + win.mDisplayFrame);
9953 } else {
9954 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009955 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009957 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009958
9959 // Now perform layout of attached windows, which usually
9960 // depend on the position of the window they are attached to.
9961 // XXX does not deal with windows that are attached to windows
9962 // that are themselves attached.
9963 for (i = topAttached; i >= 0; i--) {
9964 WindowState win = (WindowState) mWindows.get(i);
9965
9966 // If this view is GONE, then skip it -- keep the current
9967 // frame, and let the caller know so they can ignore it
9968 // if they want. (We do the normal layout for INVISIBLE
9969 // windows, since that means "perform layout as normal,
9970 // just don't display").
9971 if (win.mLayoutAttached) {
9972 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9973 + " mHaveFrame=" + win.mHaveFrame
9974 + " mViewVisibility=" + win.mViewVisibility
9975 + " mRelayoutCalled=" + win.mRelayoutCalled);
9976 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9977 || !win.mHaveFrame) {
9978 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9979 win.mLayoutSeq = seq;
9980 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9981 + win.mFrame + " mContainingFrame="
9982 + win.mContainingFrame + " mDisplayFrame="
9983 + win.mDisplayFrame);
9984 }
9985 }
9986 }
9987
9988 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009989 }
Romain Guy06882f82009-06-10 13:36:04 -07009990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009991 private final void performLayoutAndPlaceSurfacesLockedInner(
9992 boolean recoveringMemory) {
9993 final long currentTime = SystemClock.uptimeMillis();
9994 final int dw = mDisplay.getWidth();
9995 final int dh = mDisplay.getHeight();
9996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 int i;
9998
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009999 if (mFocusMayChange) {
10000 mFocusMayChange = false;
10001 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
10002 }
10003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010004 if (mFxSession == null) {
10005 mFxSession = new SurfaceSession();
10006 }
Romain Guy06882f82009-06-10 13:36:04 -070010007
Joe Onorato8a9b2202010-02-26 18:56:32 -080010008 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009
10010 // Initialize state of exiting tokens.
10011 for (i=mExitingTokens.size()-1; i>=0; i--) {
10012 mExitingTokens.get(i).hasVisible = false;
10013 }
10014
10015 // Initialize state of exiting applications.
10016 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10017 mExitingAppTokens.get(i).hasVisible = false;
10018 }
10019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020 boolean orientationChangeComplete = true;
10021 Session holdScreen = null;
10022 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010023 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010024 boolean focusDisplayed = false;
10025 boolean animating = false;
10026
10027 Surface.openTransaction();
10028 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010029 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010030 int repeats = 0;
10031 int changes = 0;
10032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010034 repeats++;
10035 if (repeats > 6) {
10036 Slog.w(TAG, "Animation repeat aborted after too many iterations");
10037 mLayoutNeeded = false;
10038 break;
10039 }
10040
10041 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
10042 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
10043 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
10044 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
10045 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
10046 assignLayersLocked();
10047 mLayoutNeeded = true;
10048 }
10049 }
10050 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
10051 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
10052 if (updateOrientationFromAppTokensLocked()) {
10053 mLayoutNeeded = true;
10054 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10055 }
10056 }
10057 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
10058 mLayoutNeeded = true;
10059 }
10060 }
10061
10062 // FIRST LOOP: Perform a layout, if needed.
10063 if (repeats < 4) {
10064 changes = performLayoutLockedInner();
10065 if (changes != 0) {
10066 continue;
10067 }
10068 } else {
10069 Slog.w(TAG, "Layout repeat skipped after too many iterations");
10070 changes = 0;
10071 }
10072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 final int transactionSequence = ++mTransactionSequence;
10074
10075 // Update animations of all applications, including those
10076 // associated with exiting/removed apps
10077 boolean tokensAnimating = false;
10078 final int NAT = mAppTokens.size();
10079 for (i=0; i<NAT; i++) {
10080 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10081 tokensAnimating = true;
10082 }
10083 }
10084 final int NEAT = mExitingAppTokens.size();
10085 for (i=0; i<NEAT; i++) {
10086 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10087 tokensAnimating = true;
10088 }
10089 }
10090
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010091 // SECOND LOOP: Execute animations and update visibility of windows.
10092
Joe Onorato8a9b2202010-02-26 18:56:32 -080010093 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010094 + transactionSequence + " tokensAnimating="
10095 + tokensAnimating);
10096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010097 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098
10099 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010100 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010101 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102
10103 mPolicy.beginAnimationLw(dw, dh);
10104
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010105 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 for (i=N-1; i>=0; i--) {
10108 WindowState w = (WindowState)mWindows.get(i);
10109
10110 final WindowManager.LayoutParams attrs = w.mAttrs;
10111
10112 if (w.mSurface != null) {
10113 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010114 if (w.commitFinishDrawingLocked(currentTime)) {
10115 if ((w.mAttrs.flags
10116 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010117 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010118 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010119 wallpaperMayChange = true;
10120 }
10121 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010122
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010123 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 if (w.stepAnimationLocked(currentTime, dw, dh)) {
10125 animating = true;
10126 //w.dump(" ");
10127 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010128 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
10129 wallpaperMayChange = true;
10130 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010131
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010132 if (mPolicy.doesForceHide(w, attrs)) {
10133 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010134 if (DEBUG_VISIBILITY) Slog.v(TAG,
10135 "Animation done that could impact force hide: "
10136 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010137 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010138 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010139 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
10140 forceHiding = true;
10141 }
10142 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10143 boolean changed;
10144 if (forceHiding) {
10145 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010146 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10147 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010148 } else {
10149 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010150 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10151 "Now policy shown: " + w);
10152 if (changed) {
10153 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010154 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010155 // Assume we will need to animate. If
10156 // we don't (because the wallpaper will
10157 // stay with the lock screen), then we will
10158 // clean up later.
10159 Animation a = mPolicy.createForceHideEnterAnimation();
10160 if (a != null) {
10161 w.setAnimation(a);
10162 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010163 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010164 if (mCurrentFocus == null ||
10165 mCurrentFocus.mLayer < w.mLayer) {
10166 // We are showing on to of the current
10167 // focus, so re-evaluate focus to make
10168 // sure it is correct.
10169 mFocusMayChange = true;
10170 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010171 }
10172 }
10173 if (changed && (attrs.flags
10174 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
10175 wallpaperMayChange = true;
10176 }
10177 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010179 mPolicy.animatingWindowLw(w, attrs);
10180 }
10181
10182 final AppWindowToken atoken = w.mAppToken;
10183 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
10184 if (atoken.lastTransactionSequence != transactionSequence) {
10185 atoken.lastTransactionSequence = transactionSequence;
10186 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
10187 atoken.startingDisplayed = false;
10188 }
10189 if ((w.isOnScreen() || w.mAttrs.type
10190 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
10191 && !w.mExiting && !w.mDestroying) {
10192 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010193 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010194 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010196 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010197 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010198 + " pv=" + w.mPolicyVisibility
10199 + " dp=" + w.mDrawPending
10200 + " cdp=" + w.mCommitDrawPending
10201 + " ah=" + w.mAttachedHidden
10202 + " th=" + atoken.hiddenRequested
10203 + " a=" + w.mAnimating);
10204 }
10205 }
10206 if (w != atoken.startingWindow) {
10207 if (!atoken.freezingScreen || !w.mAppFreezing) {
10208 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010209 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010210 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010211 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010212 "tokenMayBeDrawn: " + atoken
10213 + " freezingScreen=" + atoken.freezingScreen
10214 + " mAppFreezing=" + w.mAppFreezing);
10215 tokenMayBeDrawn = true;
10216 }
10217 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010218 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 atoken.startingDisplayed = true;
10220 }
10221 }
10222 } else if (w.mReadyToShow) {
10223 w.performShowLocked();
10224 }
10225 }
10226
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010227 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010228
10229 if (tokenMayBeDrawn) {
10230 // See if any windows have been drawn, so they (and others
10231 // associated with them) can now be shown.
10232 final int NT = mTokenList.size();
10233 for (i=0; i<NT; i++) {
10234 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
10235 if (wtoken == null) {
10236 continue;
10237 }
10238 if (wtoken.freezingScreen) {
10239 int numInteresting = wtoken.numInterestingWindows;
10240 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010241 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 "allDrawn: " + wtoken
10243 + " interesting=" + numInteresting
10244 + " drawn=" + wtoken.numDrawnWindows);
10245 wtoken.showAllWindowsLocked();
10246 unsetAppFreezingScreenLocked(wtoken, false, true);
10247 orientationChangeComplete = true;
10248 }
10249 } else if (!wtoken.allDrawn) {
10250 int numInteresting = wtoken.numInterestingWindows;
10251 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010252 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 "allDrawn: " + wtoken
10254 + " interesting=" + numInteresting
10255 + " drawn=" + wtoken.numDrawnWindows);
10256 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010257 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010258
10259 // We can now show all of the drawn windows!
10260 if (!mOpeningApps.contains(wtoken)) {
10261 wtoken.showAllWindowsLocked();
10262 }
10263 }
10264 }
10265 }
10266 }
10267
10268 // If we are ready to perform an app transition, check through
10269 // all of the app tokens to be shown and see if they are ready
10270 // to go.
10271 if (mAppTransitionReady) {
10272 int NN = mOpeningApps.size();
10273 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010274 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 "Checking " + NN + " opening apps (frozen="
10276 + mDisplayFrozen + " timeout="
10277 + mAppTransitionTimeout + ")...");
10278 if (!mDisplayFrozen && !mAppTransitionTimeout) {
10279 // If the display isn't frozen, wait to do anything until
10280 // all of the apps are ready. Otherwise just go because
10281 // we'll unfreeze the display when everyone is ready.
10282 for (i=0; i<NN && goodToGo; i++) {
10283 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010284 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 "Check opening app" + wtoken + ": allDrawn="
10286 + wtoken.allDrawn + " startingDisplayed="
10287 + wtoken.startingDisplayed);
10288 if (!wtoken.allDrawn && !wtoken.startingDisplayed
10289 && !wtoken.startingMoved) {
10290 goodToGo = false;
10291 }
10292 }
10293 }
10294 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010295 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 int transit = mNextAppTransition;
10297 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010298 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010300 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010302 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303 mAppTransitionTimeout = false;
10304 mStartingIconInTransition = false;
10305 mSkipAppTransitionAnimation = false;
10306
10307 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
10308
Dianne Hackborna8f60182009-09-01 19:01:50 -070010309 // If there are applications waiting to come to the
10310 // top of the stack, now is the time to move their windows.
10311 // (Note that we don't do apps going to the bottom
10312 // here -- we want to keep their windows in the old
10313 // Z-order until the animation completes.)
10314 if (mToTopApps.size() > 0) {
10315 NN = mAppTokens.size();
10316 for (i=0; i<NN; i++) {
10317 AppWindowToken wtoken = mAppTokens.get(i);
10318 if (wtoken.sendingToTop) {
10319 wtoken.sendingToTop = false;
10320 moveAppWindowsLocked(wtoken, NN, false);
10321 }
10322 }
10323 mToTopApps.clear();
10324 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010325
Dianne Hackborn25994b42009-09-04 14:21:19 -070010326 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010327
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010328 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010329 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010330
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010331 // The top-most window will supply the layout params,
10332 // and we will determine it below.
10333 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010334 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010335 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010336
Joe Onorato8a9b2202010-02-26 18:56:32 -080010337 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010338 "New wallpaper target=" + mWallpaperTarget
10339 + ", lower target=" + mLowerWallpaperTarget
10340 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -070010341 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010342 // Do a first pass through the tokens for two
10343 // things:
10344 // (1) Determine if both the closing and opening
10345 // app token sets are wallpaper targets, in which
10346 // case special animations are needed
10347 // (since the wallpaper needs to stay static
10348 // behind them).
10349 // (2) Find the layout params of the top-most
10350 // application window in the tokens, which is
10351 // what will control the animation theme.
10352 final int NC = mClosingApps.size();
10353 NN = NC + mOpeningApps.size();
10354 for (i=0; i<NN; i++) {
10355 AppWindowToken wtoken;
10356 int mode;
10357 if (i < NC) {
10358 wtoken = mClosingApps.get(i);
10359 mode = 1;
10360 } else {
10361 wtoken = mOpeningApps.get(i-NC);
10362 mode = 2;
10363 }
10364 if (mLowerWallpaperTarget != null) {
10365 if (mLowerWallpaperTarget.mAppToken == wtoken
10366 || mUpperWallpaperTarget.mAppToken == wtoken) {
10367 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010368 }
10369 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010370 if (wtoken.appFullscreen) {
10371 WindowState ws = wtoken.findMainWindow();
10372 if (ws != null) {
10373 // If this is a compatibility mode
10374 // window, we will always use its anim.
10375 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
10376 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010377 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010378 bestAnimLayer = Integer.MAX_VALUE;
10379 } else if (ws.mLayer > bestAnimLayer) {
10380 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010381 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010382 bestAnimLayer = ws.mLayer;
10383 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010384 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010385 }
10386 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010387
Dianne Hackborn25994b42009-09-04 14:21:19 -070010388 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010389 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010390 "Wallpaper animation!");
10391 switch (transit) {
10392 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10393 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10394 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10395 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10396 break;
10397 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10398 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10399 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10400 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10401 break;
10402 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010403 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010404 "New transit: " + transit);
10405 } else if (oldWallpaper != null) {
10406 // We are transitioning from an activity with
10407 // a wallpaper to one without.
10408 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010409 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010410 "New transit away from wallpaper: " + transit);
10411 } else if (mWallpaperTarget != null) {
10412 // We are transitioning from an activity without
10413 // a wallpaper to now showing the wallpaper
10414 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010415 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010416 "New transit into wallpaper: " + transit);
10417 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010418
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010419 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
10420 mLastEnterAnimToken = animToken;
10421 mLastEnterAnimParams = animLp;
10422 } else if (mLastEnterAnimParams != null) {
10423 animLp = mLastEnterAnimParams;
10424 mLastEnterAnimToken = null;
10425 mLastEnterAnimParams = null;
10426 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010427
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010428 // If all closing windows are obscured, then there is
10429 // no need to do an animation. This is the case, for
10430 // example, when this transition is being done behind
10431 // the lock screen.
10432 if (!mPolicy.allowAppAnimationsLw()) {
10433 animLp = null;
10434 }
10435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 NN = mOpeningApps.size();
10437 for (i=0; i<NN; i++) {
10438 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010439 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010440 "Now opening app" + wtoken);
10441 wtoken.reportedVisible = false;
10442 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010443 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010444 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010446 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010447 wtoken.showAllWindowsLocked();
10448 }
10449 NN = mClosingApps.size();
10450 for (i=0; i<NN; i++) {
10451 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010452 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010453 "Now closing app" + wtoken);
10454 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010455 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010456 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010458 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010459 // Force the allDrawn flag, because we want to start
10460 // this guy's animations regardless of whether it's
10461 // gotten drawn.
10462 wtoken.allDrawn = true;
10463 }
10464
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010465 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010467 mOpeningApps.clear();
10468 mClosingApps.clear();
10469
10470 // This has changed the visibility of windows, so perform
10471 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010472 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010474 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10475 assignLayersLocked();
10476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010477 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010478 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010479 }
10480 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010481
Dianne Hackborn16064f92010-03-25 00:47:24 -070010482 int adjResult = 0;
10483
Dianne Hackborna8f60182009-09-01 19:01:50 -070010484 if (!animating && mAppTransitionRunning) {
10485 // We have finished the animation of an app transition. To do
10486 // this, we have delayed a lot of operations like showing and
10487 // hiding apps, moving apps in Z-order, etc. The app token list
10488 // reflects the correct Z-order, but the window list may now
10489 // be out of sync with it. So here we will just rebuild the
10490 // entire app window list. Fun!
10491 mAppTransitionRunning = false;
10492 // Clear information about apps that were moving.
10493 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010494
Dianne Hackborna8f60182009-09-01 19:01:50 -070010495 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010496 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010497 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010498 moveInputMethodWindowsIfNeededLocked(false);
10499 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010500 // Since the window list has been rebuilt, focus might
10501 // have to be recomputed since the actual order of windows
10502 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010503 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010504 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010505
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010506 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010507 // At this point, there was a window with a wallpaper that
10508 // was force hiding other windows behind it, but now it
10509 // is going away. This may be simple -- just animate
10510 // away the wallpaper and its window -- or it may be
10511 // hard -- the wallpaper now needs to be shown behind
10512 // something that was hidden.
10513 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010514 if (mLowerWallpaperTarget != null
10515 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010516 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010517 "wallpaperForceHiding changed with lower="
10518 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010519 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010520 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10521 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10522 if (mLowerWallpaperTarget.mAppToken.hidden) {
10523 // The lower target has become hidden before we
10524 // actually started the animation... let's completely
10525 // re-evaluate everything.
10526 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010527 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010528 }
10529 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010530 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010531 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010532 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010533 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010534 + " NEW: " + mWallpaperTarget
10535 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010536 if (mLowerWallpaperTarget == null) {
10537 // Whoops, we don't need a special wallpaper animation.
10538 // Clear them out.
10539 forceHiding = false;
10540 for (i=N-1; i>=0; i--) {
10541 WindowState w = (WindowState)mWindows.get(i);
10542 if (w.mSurface != null) {
10543 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010544 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010545 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010546 forceHiding = true;
10547 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10548 if (!w.mAnimating) {
10549 // We set the animation above so it
10550 // is not yet running.
10551 w.clearAnimation();
10552 }
10553 }
10554 }
10555 }
10556 }
10557 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010558
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010559 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010560 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010561 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010562 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010563 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010564
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010565 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010566 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010567 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010568 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010569 assignLayersLocked();
10570 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010571 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010572 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010573 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010574 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010575
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010576 if (mFocusMayChange) {
10577 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010578 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010579 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010580 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010581 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010582 }
10583
10584 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010585 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010586 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010587
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010588 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10589 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010590
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010591 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010592
10593 // THIRD LOOP: Update the surfaces of all windows.
10594
10595 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10596
10597 boolean obscured = false;
10598 boolean blurring = false;
10599 boolean dimming = false;
10600 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010601 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010602 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010603
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010604 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010606 for (i=N-1; i>=0; i--) {
10607 WindowState w = (WindowState)mWindows.get(i);
10608
10609 boolean displayed = false;
10610 final WindowManager.LayoutParams attrs = w.mAttrs;
10611 final int attrFlags = attrs.flags;
10612
10613 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010614 // XXX NOTE: The logic here could be improved. We have
10615 // the decision about whether to resize a window separated
10616 // from whether to hide the surface. This can cause us to
10617 // resize a surface even if we are going to hide it. You
10618 // can see this by (1) holding device in landscape mode on
10619 // home screen; (2) tapping browser icon (device will rotate
10620 // to landscape; (3) tap home. The wallpaper will be resized
10621 // in step 2 but then immediately hidden, causing us to
10622 // have to resize and then redraw it again in step 3. It
10623 // would be nice to figure out how to avoid this, but it is
10624 // difficult because we do need to resize surfaces in some
10625 // cases while they are hidden such as when first showing a
10626 // window.
10627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010628 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010629 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010630 TAG, "Placing surface #" + i + " " + w.mSurface
10631 + ": new=" + w.mShownFrame + ", old="
10632 + w.mLastShownFrame);
10633
10634 boolean resize;
10635 int width, height;
10636 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10637 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10638 w.mLastRequestedHeight != w.mRequestedHeight;
10639 // for a scaled surface, we just want to use
10640 // the requested size.
10641 width = w.mRequestedWidth;
10642 height = w.mRequestedHeight;
10643 w.mLastRequestedWidth = width;
10644 w.mLastRequestedHeight = height;
10645 w.mLastShownFrame.set(w.mShownFrame);
10646 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010647 if (SHOW_TRANSACTIONS) logSurface(w,
10648 "POS " + w.mShownFrame.left
10649 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010650 w.mSurfaceX = w.mShownFrame.left;
10651 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10653 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010654 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010655 if (!recoveringMemory) {
10656 reclaimSomeSurfaceMemoryLocked(w, "position");
10657 }
10658 }
10659 } else {
10660 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10661 width = w.mShownFrame.width();
10662 height = w.mShownFrame.height();
10663 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 }
10665
10666 if (resize) {
10667 if (width < 1) width = 1;
10668 if (height < 1) height = 1;
10669 if (w.mSurface != null) {
10670 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010671 if (SHOW_TRANSACTIONS) logSurface(w,
10672 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010673 + w.mShownFrame.top + " SIZE "
10674 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010675 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010676 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010677 w.mSurfaceW = width;
10678 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010680 w.mSurfaceX = w.mShownFrame.left;
10681 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010682 w.mSurface.setPosition(w.mShownFrame.left,
10683 w.mShownFrame.top);
10684 } catch (RuntimeException e) {
10685 // If something goes wrong with the surface (such
10686 // as running out of memory), don't take down the
10687 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010688 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 + "size=(" + width + "x" + height
10690 + "), pos=(" + w.mShownFrame.left
10691 + "," + w.mShownFrame.top + ")", e);
10692 if (!recoveringMemory) {
10693 reclaimSomeSurfaceMemoryLocked(w, "size");
10694 }
10695 }
10696 }
10697 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010698 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010699 w.mContentInsetsChanged =
10700 !w.mLastContentInsets.equals(w.mContentInsets);
10701 w.mVisibleInsetsChanged =
10702 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010703 boolean configChanged =
10704 w.mConfiguration != mCurConfiguration
10705 && (w.mConfiguration == null
10706 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010707 if (DEBUG_CONFIGURATION && configChanged) {
10708 Slog.v(TAG, "Win " + w + " config changed: "
10709 + mCurConfiguration);
10710 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010711 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010712 + ": configChanged=" + configChanged
10713 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010714 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010715 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010716 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010717 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010718 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010719 w.mLastFrame.set(w.mFrame);
10720 w.mLastContentInsets.set(w.mContentInsets);
10721 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010722 // If the screen is currently frozen, then keep
10723 // it frozen until this window draws at its new
10724 // orientation.
10725 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010726 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010727 "Resizing while display frozen: " + w);
10728 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010729 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010730 mWindowsFreezingScreen = true;
10731 // XXX should probably keep timeout from
10732 // when we first froze the display.
10733 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10734 mH.sendMessageDelayed(mH.obtainMessage(
10735 H.WINDOW_FREEZE_TIMEOUT), 2000);
10736 }
10737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 // If the orientation is changing, then we need to
10739 // hold off on unfreezing the display until this
10740 // window has been redrawn; to do that, we need
10741 // to go through the process of getting informed
10742 // by the application when it has finished drawing.
10743 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010744 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010745 "Orientation start waiting for draw in "
10746 + w + ", surface " + w.mSurface);
10747 w.mDrawPending = true;
10748 w.mCommitDrawPending = false;
10749 w.mReadyToShow = false;
10750 if (w.mAppToken != null) {
10751 w.mAppToken.allDrawn = false;
10752 }
10753 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010754 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010755 "Resizing window " + w + " to " + w.mFrame);
10756 mResizingWindows.add(w);
10757 } else if (w.mOrientationChanging) {
10758 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010759 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010760 "Orientation not waiting for draw in "
10761 + w + ", surface " + w.mSurface);
10762 w.mOrientationChanging = false;
10763 }
10764 }
10765 }
10766
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010767 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010768 if (!w.mLastHidden) {
10769 //dump();
Dianne Hackborn5943c202010-04-12 21:36:49 -070010770 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Window hiding: waitingToShow="
10771 + w.mRootToken.waitingToShow + " polvis="
10772 + w.mPolicyVisibility + " atthid="
10773 + w.mAttachedHidden + " tokhid="
10774 + w.mRootToken.hidden + " vis="
10775 + w.mViewVisibility);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010776 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010777 if (SHOW_TRANSACTIONS) logSurface(w,
10778 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010780 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 try {
10782 w.mSurface.hide();
10783 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010784 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010785 }
10786 }
10787 mKeyWaiter.releasePendingPointerLocked(w.mSession);
10788 }
10789 // If we are waiting for this window to handle an
10790 // orientation change, well, it is hidden, so
10791 // doesn't really matter. Note that this does
10792 // introduce a potential glitch if the window
10793 // becomes unhidden before it has drawn for the
10794 // new orientation.
10795 if (w.mOrientationChanging) {
10796 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010797 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010798 "Orientation change skips hidden " + w);
10799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 } else if (w.mLastLayer != w.mAnimLayer
10801 || w.mLastAlpha != w.mShownAlpha
10802 || w.mLastDsDx != w.mDsDx
10803 || w.mLastDtDx != w.mDtDx
10804 || w.mLastDsDy != w.mDsDy
10805 || w.mLastDtDy != w.mDtDy
10806 || w.mLastHScale != w.mHScale
10807 || w.mLastVScale != w.mVScale
10808 || w.mLastHidden) {
10809 displayed = true;
10810 w.mLastAlpha = w.mShownAlpha;
10811 w.mLastLayer = w.mAnimLayer;
10812 w.mLastDsDx = w.mDsDx;
10813 w.mLastDtDx = w.mDtDx;
10814 w.mLastDsDy = w.mDsDy;
10815 w.mLastDtDy = w.mDtDy;
10816 w.mLastHScale = w.mHScale;
10817 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010818 if (SHOW_TRANSACTIONS) logSurface(w,
10819 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010820 + " matrix=[" + (w.mDsDx*w.mHScale)
10821 + "," + (w.mDtDx*w.mVScale)
10822 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010823 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 if (w.mSurface != null) {
10825 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010826 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010827 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010828 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 w.mSurface.setLayer(w.mAnimLayer);
10830 w.mSurface.setMatrix(
10831 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10832 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10833 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010834 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010835 if (!recoveringMemory) {
10836 reclaimSomeSurfaceMemoryLocked(w, "update");
10837 }
10838 }
10839 }
10840
10841 if (w.mLastHidden && !w.mDrawPending
10842 && !w.mCommitDrawPending
10843 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010844 if (SHOW_TRANSACTIONS) logSurface(w,
10845 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010846 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010847 + " during relayout");
10848 if (showSurfaceRobustlyLocked(w)) {
10849 w.mHasDrawn = true;
10850 w.mLastHidden = false;
10851 } else {
10852 w.mOrientationChanging = false;
10853 }
10854 }
10855 if (w.mSurface != null) {
10856 w.mToken.hasVisible = true;
10857 }
10858 } else {
10859 displayed = true;
10860 }
10861
10862 if (displayed) {
10863 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010864 if (attrs.width == LayoutParams.MATCH_PARENT
10865 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010866 covered = true;
10867 }
10868 }
10869 if (w.mOrientationChanging) {
10870 if (w.mDrawPending || w.mCommitDrawPending) {
10871 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010872 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 "Orientation continue waiting for draw in " + w);
10874 } else {
10875 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010876 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010877 "Orientation change complete in " + w);
10878 }
10879 }
10880 w.mToken.hasVisible = true;
10881 }
10882 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010883 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010884 "Orientation change skips hidden " + w);
10885 w.mOrientationChanging = false;
10886 }
10887
10888 final boolean canBeSeen = w.isDisplayedLw();
10889
10890 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10891 focusDisplayed = true;
10892 }
10893
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010894 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010897 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 if (w.mSurface != null) {
10899 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10900 holdScreen = w.mSession;
10901 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010902 if (!syswin && w.mAttrs.screenBrightness >= 0
10903 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010904 screenBrightness = w.mAttrs.screenBrightness;
10905 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010906 if (!syswin && w.mAttrs.buttonBrightness >= 0
10907 && buttonBrightness < 0) {
10908 buttonBrightness = w.mAttrs.buttonBrightness;
10909 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010910 if (canBeSeen
10911 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10912 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10913 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010914 syswin = true;
10915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010916 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010917
Dianne Hackborn25994b42009-09-04 14:21:19 -070010918 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10919 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010920 // This window completely covers everything behind it,
10921 // so we want to leave all of them as unblurred (for
10922 // performance reasons).
10923 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010924 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010925 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010926 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010927 obscured = true;
10928 if (mBackgroundFillerSurface == null) {
10929 try {
10930 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010931 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010932 0, dw, dh,
10933 PixelFormat.OPAQUE,
10934 Surface.FX_SURFACE_NORMAL);
10935 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010936 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010937 }
10938 }
10939 try {
10940 mBackgroundFillerSurface.setPosition(0, 0);
10941 mBackgroundFillerSurface.setSize(dw, dh);
10942 // Using the same layer as Dim because they will never be shown at the
10943 // same time.
10944 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10945 mBackgroundFillerSurface.show();
10946 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010947 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010948 }
10949 backgroundFillerShown = true;
10950 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010951 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010952 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010953 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010954 + ": blurring=" + blurring
10955 + " obscured=" + obscured
10956 + " displayed=" + displayed);
10957 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10958 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010959 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010960 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010961 if (mDimAnimator == null) {
10962 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010964 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010965 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 }
10968 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10969 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010970 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010973 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 + mBlurSurface + ": CREATE");
10975 try {
Romain Guy06882f82009-06-10 13:36:04 -070010976 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010977 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 -1, 16, 16,
10979 PixelFormat.OPAQUE,
10980 Surface.FX_SURFACE_BLUR);
10981 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010982 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 }
10984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010985 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010986 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10987 + mBlurSurface + ": pos=(0,0) (" +
10988 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010989 mBlurSurface.setPosition(0, 0);
10990 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010991 mBlurSurface.setLayer(w.mAnimLayer-2);
10992 if (!mBlurShown) {
10993 try {
10994 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10995 + mBlurSurface + ": SHOW");
10996 mBlurSurface.show();
10997 } catch (RuntimeException e) {
10998 Slog.w(TAG, "Failure showing blur surface", e);
10999 }
11000 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011001 }
11002 }
11003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011004 }
11005 }
11006 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011007
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011008 if (obscuredChanged && mWallpaperTarget == w) {
11009 // This is the wallpaper target and its obscured state
11010 // changed... make sure the current wallaper's visibility
11011 // has been updated accordingly.
11012 updateWallpaperVisibilityLocked();
11013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011014 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011015
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011016 if (backgroundFillerShown == false && mBackgroundFillerShown) {
11017 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011018 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011019 try {
11020 mBackgroundFillerSurface.hide();
11021 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011022 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011023 }
11024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011025
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011026 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080011027 animating |= mDimAnimator.updateSurface(dimming, currentTime,
11028 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 }
Romain Guy06882f82009-06-10 13:36:04 -070011030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011032 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 + ": HIDE");
11034 try {
11035 mBlurSurface.hide();
11036 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011037 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011038 }
11039 mBlurShown = false;
11040 }
11041
Joe Onorato8a9b2202010-02-26 18:56:32 -080011042 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011043 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011044 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011045 }
11046
11047 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070011048
Joe Onorato8a9b2202010-02-26 18:56:32 -080011049 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 "With display frozen, orientationChangeComplete="
11051 + orientationChangeComplete);
11052 if (orientationChangeComplete) {
11053 if (mWindowsFreezingScreen) {
11054 mWindowsFreezingScreen = false;
11055 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
11056 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011057 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011058 }
Romain Guy06882f82009-06-10 13:36:04 -070011059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 i = mResizingWindows.size();
11061 if (i > 0) {
11062 do {
11063 i--;
11064 WindowState win = mResizingWindows.get(i);
11065 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011066 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
11067 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011068 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011069 boolean configChanged =
11070 win.mConfiguration != mCurConfiguration
11071 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011072 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
11073 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
11074 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011075 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011076 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011077 + " / " + mCurConfiguration + " / 0x"
11078 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011079 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011080 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011081 win.mClient.resized(win.mFrame.width(),
11082 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011083 win.mLastVisibleInsets, win.mDrawPending,
11084 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011085 win.mContentInsetsChanged = false;
11086 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011087 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011088 } catch (RemoteException e) {
11089 win.mOrientationChanging = false;
11090 }
11091 } while (i > 0);
11092 mResizingWindows.clear();
11093 }
Romain Guy06882f82009-06-10 13:36:04 -070011094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011095 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011096 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011097 i = mDestroySurface.size();
11098 if (i > 0) {
11099 do {
11100 i--;
11101 WindowState win = mDestroySurface.get(i);
11102 win.mDestroying = false;
11103 if (mInputMethodWindow == win) {
11104 mInputMethodWindow = null;
11105 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011106 if (win == mWallpaperTarget) {
11107 wallpaperDestroyed = true;
11108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011109 win.destroySurfaceLocked();
11110 } while (i > 0);
11111 mDestroySurface.clear();
11112 }
11113
11114 // Time to remove any exiting tokens?
11115 for (i=mExitingTokens.size()-1; i>=0; i--) {
11116 WindowToken token = mExitingTokens.get(i);
11117 if (!token.hasVisible) {
11118 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011119 if (token.windowType == TYPE_WALLPAPER) {
11120 mWallpaperTokens.remove(token);
11121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011122 }
11123 }
11124
11125 // Time to remove any exiting applications?
11126 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
11127 AppWindowToken token = mExitingAppTokens.get(i);
11128 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070011129 // Make sure there is no animation running on this token,
11130 // so any windows associated with it will be removed as
11131 // soon as their animations are complete
11132 token.animation = null;
11133 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011134 mAppTokens.remove(token);
11135 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011136 if (mLastEnterAnimToken == token) {
11137 mLastEnterAnimToken = null;
11138 mLastEnterAnimParams = null;
11139 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011140 }
11141 }
11142
Dianne Hackborna8f60182009-09-01 19:01:50 -070011143 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011144
Dianne Hackborna8f60182009-09-01 19:01:50 -070011145 if (!animating && mAppTransitionRunning) {
11146 // We have finished the animation of an app transition. To do
11147 // this, we have delayed a lot of operations like showing and
11148 // hiding apps, moving apps in Z-order, etc. The app token list
11149 // reflects the correct Z-order, but the window list may now
11150 // be out of sync with it. So here we will just rebuild the
11151 // entire app window list. Fun!
11152 mAppTransitionRunning = false;
11153 needRelayout = true;
11154 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011155 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070011156 // Clear information about apps that were moving.
11157 mToBottomApps.clear();
11158 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 if (focusDisplayed) {
11161 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
11162 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011163 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011164 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011165 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011166 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011167 requestAnimationLocked(0);
11168 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
11170 }
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011171
11172 if (DEBUG_FREEZE) Slog.v(TAG, "Layout: mDisplayFrozen=" + mDisplayFrozen
11173 + " holdScreen=" + holdScreen);
11174 if (!mDisplayFrozen) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011175 setHoldScreenLocked(holdScreen != null);
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011176 if (screenBrightness < 0 || screenBrightness > 1.0f) {
11177 mPowerManager.setScreenBrightnessOverride(-1);
11178 } else {
11179 mPowerManager.setScreenBrightnessOverride((int)
11180 (screenBrightness * Power.BRIGHTNESS_ON));
11181 }
11182 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
11183 mPowerManager.setButtonBrightnessOverride(-1);
11184 } else {
11185 mPowerManager.setButtonBrightnessOverride((int)
11186 (buttonBrightness * Power.BRIGHTNESS_ON));
11187 }
11188 if (holdScreen != mHoldingScreenOn) {
11189 mHoldingScreenOn = holdScreen;
11190 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
11191 mH.sendMessage(m);
11192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011194
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011195 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011196 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011197 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
11198 LocalPowerManager.BUTTON_EVENT, true);
11199 mTurnOnScreen = false;
11200 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011201
11202 // Check to see if we are now in a state where the screen should
11203 // be enabled, because the window obscured flags have changed.
11204 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011205 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011206
11207 /**
11208 * Must be called with the main window manager lock held.
11209 */
11210 void setHoldScreenLocked(boolean holding) {
11211 boolean state = mHoldingScreenWakeLock.isHeld();
11212 if (holding != state) {
11213 if (holding) {
11214 mHoldingScreenWakeLock.acquire();
11215 } else {
11216 mPolicy.screenOnStoppedLw();
11217 mHoldingScreenWakeLock.release();
11218 }
11219 }
11220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011221
11222 void requestAnimationLocked(long delay) {
11223 if (!mAnimationPending) {
11224 mAnimationPending = true;
11225 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
11226 }
11227 }
Romain Guy06882f82009-06-10 13:36:04 -070011228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011229 /**
11230 * Have the surface flinger show a surface, robustly dealing with
11231 * error conditions. In particular, if there is not enough memory
11232 * to show the surface, then we will try to get rid of other surfaces
11233 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070011234 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011235 * @return Returns true if the surface was successfully shown.
11236 */
11237 boolean showSurfaceRobustlyLocked(WindowState win) {
11238 try {
11239 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011240 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011241 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011242 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011243 if (DEBUG_VISIBILITY) Slog.v(TAG,
11244 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011245 win.mTurnOnScreen = false;
11246 mTurnOnScreen = true;
11247 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011248 }
11249 return true;
11250 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011251 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011252 }
Romain Guy06882f82009-06-10 13:36:04 -070011253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011254 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070011255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011256 return false;
11257 }
Romain Guy06882f82009-06-10 13:36:04 -070011258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011259 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
11260 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070011261
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011262 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011263 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070011264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011265 if (mForceRemoves == null) {
11266 mForceRemoves = new ArrayList<WindowState>();
11267 }
Romain Guy06882f82009-06-10 13:36:04 -070011268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011269 long callingIdentity = Binder.clearCallingIdentity();
11270 try {
11271 // There was some problem... first, do a sanity check of the
11272 // window list to make sure we haven't left any dangling surfaces
11273 // around.
11274 int N = mWindows.size();
11275 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011276 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011277 for (int i=0; i<N; i++) {
11278 WindowState ws = (WindowState)mWindows.get(i);
11279 if (ws.mSurface != null) {
11280 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011281 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 + ws + " surface=" + ws.mSurface
11283 + " token=" + win.mToken
11284 + " pid=" + ws.mSession.mPid
11285 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011286 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011287 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011288 ws.mSurface = null;
11289 mForceRemoves.add(ws);
11290 i--;
11291 N--;
11292 leakedSurface = true;
11293 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011294 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011295 + ws + " surface=" + ws.mSurface
11296 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011297 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011298 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 ws.mSurface = null;
11300 leakedSurface = true;
11301 }
11302 }
11303 }
Romain Guy06882f82009-06-10 13:36:04 -070011304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011305 boolean killedApps = false;
11306 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011307 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011308 SparseIntArray pidCandidates = new SparseIntArray();
11309 for (int i=0; i<N; i++) {
11310 WindowState ws = (WindowState)mWindows.get(i);
11311 if (ws.mSurface != null) {
11312 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
11313 }
11314 }
11315 if (pidCandidates.size() > 0) {
11316 int[] pids = new int[pidCandidates.size()];
11317 for (int i=0; i<pids.length; i++) {
11318 pids[i] = pidCandidates.keyAt(i);
11319 }
11320 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070011321 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011322 killedApps = true;
11323 }
11324 } catch (RemoteException e) {
11325 }
11326 }
11327 }
Romain Guy06882f82009-06-10 13:36:04 -070011328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 if (leakedSurface || killedApps) {
11330 // We managed to reclaim some memory, so get rid of the trouble
11331 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011332 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011333 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011334 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011335 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011336 win.mSurface = null;
11337 }
Romain Guy06882f82009-06-10 13:36:04 -070011338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 try {
11340 win.mClient.dispatchGetNewSurface();
11341 } catch (RemoteException e) {
11342 }
11343 }
11344 } finally {
11345 Binder.restoreCallingIdentity(callingIdentity);
11346 }
11347 }
Romain Guy06882f82009-06-10 13:36:04 -070011348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 private boolean updateFocusedWindowLocked(int mode) {
11350 WindowState newFocus = computeFocusedWindowLocked();
11351 if (mCurrentFocus != newFocus) {
11352 // This check makes sure that we don't already have the focus
11353 // change message pending.
11354 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
11355 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011356 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
11358 final WindowState oldFocus = mCurrentFocus;
11359 mCurrentFocus = newFocus;
11360 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070011361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011362 final WindowState imWindow = mInputMethodWindow;
11363 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011364 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011366 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
11367 mLayoutNeeded = true;
11368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
11370 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011371 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
11372 // Client will do the layout, but we need to assign layers
11373 // for handleNewWindowLocked() below.
11374 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011375 }
11376 }
Romain Guy06882f82009-06-10 13:36:04 -070011377
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011378 if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
11379 mKeyWaiter.handleNewWindowLocked(newFocus);
11380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011381 return true;
11382 }
11383 return false;
11384 }
11385
11386 private WindowState computeFocusedWindowLocked() {
11387 WindowState result = null;
11388 WindowState win;
11389
11390 int i = mWindows.size() - 1;
11391 int nextAppIndex = mAppTokens.size()-1;
11392 WindowToken nextApp = nextAppIndex >= 0
11393 ? mAppTokens.get(nextAppIndex) : null;
11394
11395 while (i >= 0) {
11396 win = (WindowState)mWindows.get(i);
11397
Joe Onorato8a9b2202010-02-26 18:56:32 -080011398 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 TAG, "Looking for focus: " + i
11400 + " = " + win
11401 + ", flags=" + win.mAttrs.flags
11402 + ", canReceive=" + win.canReceiveKeys());
11403
11404 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011406 // If this window's application has been removed, just skip it.
11407 if (thisApp != null && thisApp.removed) {
11408 i--;
11409 continue;
11410 }
Romain Guy06882f82009-06-10 13:36:04 -070011411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412 // If there is a focused app, don't allow focus to go to any
11413 // windows below it. If this is an application window, step
11414 // through the app tokens until we find its app.
11415 if (thisApp != null && nextApp != null && thisApp != nextApp
11416 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11417 int origAppIndex = nextAppIndex;
11418 while (nextAppIndex > 0) {
11419 if (nextApp == mFocusedApp) {
11420 // Whoops, we are below the focused app... no focus
11421 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011422 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 TAG, "Reached focused app: " + mFocusedApp);
11424 return null;
11425 }
11426 nextAppIndex--;
11427 nextApp = mAppTokens.get(nextAppIndex);
11428 if (nextApp == thisApp) {
11429 break;
11430 }
11431 }
11432 if (thisApp != nextApp) {
11433 // Uh oh, the app token doesn't exist! This shouldn't
11434 // happen, but if it does we can get totally hosed...
11435 // so restart at the original app.
11436 nextAppIndex = origAppIndex;
11437 nextApp = mAppTokens.get(nextAppIndex);
11438 }
11439 }
11440
11441 // Dispatch to this window if it is wants key events.
11442 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011443 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 TAG, "Found focus @ " + i + " = " + win);
11445 result = win;
11446 break;
11447 }
11448
11449 i--;
11450 }
11451
11452 return result;
11453 }
11454
11455 private void startFreezingDisplayLocked() {
11456 if (mDisplayFrozen) {
Chris Tate2ad63a92009-03-25 17:36:48 -070011457 // Freezing the display also suspends key event delivery, to
11458 // keep events from going astray while the display is reconfigured.
11459 // If someone has changed orientation again while the screen is
11460 // still frozen, the events will continue to be blocked while the
11461 // successive orientation change is processed. To prevent spurious
11462 // ANRs, we reset the event dispatch timeout in this case.
11463 synchronized (mKeyWaiter) {
11464 mKeyWaiter.mWasFrozen = true;
11465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011466 return;
11467 }
Romain Guy06882f82009-06-10 13:36:04 -070011468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011472 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011473 if (mFreezeGcPending != 0) {
11474 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011475 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011476 mH.removeMessages(H.FORCE_GC);
11477 Runtime.getRuntime().gc();
11478 mFreezeGcPending = now;
11479 }
11480 } else {
11481 mFreezeGcPending = now;
11482 }
Romain Guy06882f82009-06-10 13:36:04 -070011483
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011484 if (DEBUG_FREEZE) Slog.v(TAG, "*** FREEZING DISPLAY", new RuntimeException());
11485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011486 mDisplayFrozen = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011487 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11488 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011489 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011490 mAppTransitionReady = true;
11491 }
Romain Guy06882f82009-06-10 13:36:04 -070011492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011493 if (PROFILE_ORIENTATION) {
11494 File file = new File("/data/system/frozen");
11495 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11496 }
11497 Surface.freezeDisplay(0);
11498 }
Romain Guy06882f82009-06-10 13:36:04 -070011499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500 private void stopFreezingDisplayLocked() {
11501 if (!mDisplayFrozen) {
11502 return;
11503 }
Romain Guy06882f82009-06-10 13:36:04 -070011504
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011505 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11506 return;
11507 }
11508
Dianne Hackbornce73c1e2010-04-12 23:11:38 -070011509 if (DEBUG_FREEZE) Slog.v(TAG, "*** UNFREEZING DISPLAY", new RuntimeException());
11510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011511 mDisplayFrozen = false;
11512 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11513 if (PROFILE_ORIENTATION) {
11514 Debug.stopMethodTracing();
11515 }
11516 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070011517
Chris Tate2ad63a92009-03-25 17:36:48 -070011518 // Reset the key delivery timeout on unfreeze, too. We force a wakeup here
11519 // too because regular key delivery processing should resume immediately.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011520 synchronized (mKeyWaiter) {
11521 mKeyWaiter.mWasFrozen = true;
11522 mKeyWaiter.notifyAll();
11523 }
11524
Christopher Tateb696aee2010-04-02 19:08:30 -070011525 // While the display is frozen we don't re-compute the orientation
11526 // to avoid inconsistent states. However, something interesting
11527 // could have actually changed during that time so re-evaluate it
11528 // now to catch that.
11529 if (updateOrientationFromAppTokensLocked()) {
11530 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11531 }
11532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011533 // A little kludge: a lot could have happened while the
11534 // display was frozen, so now that we are coming back we
11535 // do a gc so that any remote references the system
11536 // processes holds on others can be released if they are
11537 // no longer needed.
11538 mH.removeMessages(H.FORCE_GC);
11539 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11540 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542 mScreenFrozenLock.release();
11543 }
Romain Guy06882f82009-06-10 13:36:04 -070011544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011545 @Override
11546 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11547 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11548 != PackageManager.PERMISSION_GRANTED) {
11549 pw.println("Permission Denial: can't dump WindowManager from from pid="
11550 + Binder.getCallingPid()
11551 + ", uid=" + Binder.getCallingUid());
11552 return;
11553 }
Romain Guy06882f82009-06-10 13:36:04 -070011554
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011555 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11556 pw.println("Input Dispatcher State:");
11557 mInputManager.dump(pw);
11558 } else {
11559 pw.println("Input State:");
11560 mQueue.dump(pw, " ");
11561 }
Dianne Hackborna2e92262010-03-02 17:19:29 -080011562 pw.println(" ");
11563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 synchronized(mWindowMap) {
11565 pw.println("Current Window Manager state:");
11566 for (int i=mWindows.size()-1; i>=0; i--) {
11567 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011568 pw.print(" Window #"); pw.print(i); pw.print(' ');
11569 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011570 w.dump(pw, " ");
11571 }
11572 if (mInputMethodDialogs.size() > 0) {
11573 pw.println(" ");
11574 pw.println(" Input method dialogs:");
11575 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11576 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011577 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 }
11579 }
11580 if (mPendingRemove.size() > 0) {
11581 pw.println(" ");
11582 pw.println(" Remove pending for:");
11583 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11584 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011585 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11586 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 w.dump(pw, " ");
11588 }
11589 }
11590 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11591 pw.println(" ");
11592 pw.println(" Windows force removing:");
11593 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11594 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011595 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11596 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011597 w.dump(pw, " ");
11598 }
11599 }
11600 if (mDestroySurface.size() > 0) {
11601 pw.println(" ");
11602 pw.println(" Windows waiting to destroy their surface:");
11603 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11604 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011605 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11606 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011607 w.dump(pw, " ");
11608 }
11609 }
11610 if (mLosingFocus.size() > 0) {
11611 pw.println(" ");
11612 pw.println(" Windows losing focus:");
11613 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11614 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011615 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11616 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 w.dump(pw, " ");
11618 }
11619 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011620 if (mResizingWindows.size() > 0) {
11621 pw.println(" ");
11622 pw.println(" Windows waiting to resize:");
11623 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11624 WindowState w = mResizingWindows.get(i);
11625 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11626 pw.print(w); pw.println(":");
11627 w.dump(pw, " ");
11628 }
11629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011630 if (mSessions.size() > 0) {
11631 pw.println(" ");
11632 pw.println(" All active sessions:");
11633 Iterator<Session> it = mSessions.iterator();
11634 while (it.hasNext()) {
11635 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011636 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011637 s.dump(pw, " ");
11638 }
11639 }
11640 if (mTokenMap.size() > 0) {
11641 pw.println(" ");
11642 pw.println(" All tokens:");
11643 Iterator<WindowToken> it = mTokenMap.values().iterator();
11644 while (it.hasNext()) {
11645 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011646 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011647 token.dump(pw, " ");
11648 }
11649 }
11650 if (mTokenList.size() > 0) {
11651 pw.println(" ");
11652 pw.println(" Window token list:");
11653 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011654 pw.print(" #"); pw.print(i); pw.print(": ");
11655 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011656 }
11657 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011658 if (mWallpaperTokens.size() > 0) {
11659 pw.println(" ");
11660 pw.println(" Wallpaper tokens:");
11661 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11662 WindowToken token = mWallpaperTokens.get(i);
11663 pw.print(" Wallpaper #"); pw.print(i);
11664 pw.print(' '); pw.print(token); pw.println(':');
11665 token.dump(pw, " ");
11666 }
11667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011668 if (mAppTokens.size() > 0) {
11669 pw.println(" ");
11670 pw.println(" Application tokens in Z order:");
11671 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011672 pw.print(" App #"); pw.print(i); pw.print(": ");
11673 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 }
11675 }
11676 if (mFinishedStarting.size() > 0) {
11677 pw.println(" ");
11678 pw.println(" Finishing start of application tokens:");
11679 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11680 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011681 pw.print(" Finished Starting #"); pw.print(i);
11682 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011683 token.dump(pw, " ");
11684 }
11685 }
11686 if (mExitingTokens.size() > 0) {
11687 pw.println(" ");
11688 pw.println(" Exiting tokens:");
11689 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11690 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011691 pw.print(" Exiting #"); pw.print(i);
11692 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011693 token.dump(pw, " ");
11694 }
11695 }
11696 if (mExitingAppTokens.size() > 0) {
11697 pw.println(" ");
11698 pw.println(" Exiting application tokens:");
11699 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11700 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011701 pw.print(" Exiting App #"); pw.print(i);
11702 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 token.dump(pw, " ");
11704 }
11705 }
11706 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011707 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11708 pw.print(" mLastFocus="); pw.println(mLastFocus);
11709 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11710 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11711 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011712 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011713 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11714 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11715 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11716 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011717 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11718 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11719 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011720 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11721 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11722 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11723 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011724 if (mDimAnimator != null) {
11725 mDimAnimator.printTo(pw);
11726 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011727 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011728 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011729 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011730 pw.print(mInputMethodAnimLayerAdjustment);
11731 pw.print(" mWallpaperAnimLayerAdjustment=");
11732 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011733 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11734 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011735 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11736 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011737 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11738 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011739 pw.print(" mRotation="); pw.print(mRotation);
11740 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11741 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11742 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11743 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11744 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11745 pw.print(" mNextAppTransition=0x");
11746 pw.print(Integer.toHexString(mNextAppTransition));
11747 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011748 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011749 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011750 if (mNextAppTransitionPackage != null) {
11751 pw.print(" mNextAppTransitionPackage=");
11752 pw.print(mNextAppTransitionPackage);
11753 pw.print(", mNextAppTransitionEnter=0x");
11754 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11755 pw.print(", mNextAppTransitionExit=0x");
11756 pw.print(Integer.toHexString(mNextAppTransitionExit));
11757 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011758 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11759 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011760 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11761 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11762 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11763 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011764 if (mOpeningApps.size() > 0) {
11765 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11766 }
11767 if (mClosingApps.size() > 0) {
11768 pw.print(" mClosingApps="); pw.println(mClosingApps);
11769 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011770 if (mToTopApps.size() > 0) {
11771 pw.print(" mToTopApps="); pw.println(mToTopApps);
11772 }
11773 if (mToBottomApps.size() > 0) {
11774 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11775 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011776 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11777 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 pw.println(" KeyWaiter state:");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011779 pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin);
11780 pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
11781 pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished);
11782 pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
11783 pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
11784 pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 }
11786 }
11787
11788 public void monitor() {
11789 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011790 synchronized (mKeyguardTokenWatcher) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011791 synchronized (mKeyWaiter) { }
11792 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011793
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011794 public void virtualKeyFeedback(KeyEvent event) {
11795 mPolicy.keyFeedbackFromInput(event);
11796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011797
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011798 /**
11799 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011800 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011801 */
11802 private static class DimAnimator {
11803 Surface mDimSurface;
11804 boolean mDimShown = false;
11805 float mDimCurrentAlpha;
11806 float mDimTargetAlpha;
11807 float mDimDeltaPerMs;
11808 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011809
11810 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011811
11812 DimAnimator (SurfaceSession session) {
11813 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011814 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011815 + mDimSurface + ": CREATE");
11816 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011817 mDimSurface = new Surface(session, 0,
11818 "DimSurface",
11819 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011820 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011821 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011822 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011823 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011824 }
11825 }
11826 }
11827
11828 /**
11829 * Show the dim surface.
11830 */
11831 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011832 if (!mDimShown) {
11833 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11834 dw + "x" + dh + ")");
11835 mDimShown = true;
11836 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011837 mLastDimWidth = dw;
11838 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011839 mDimSurface.setPosition(0, 0);
11840 mDimSurface.setSize(dw, dh);
11841 mDimSurface.show();
11842 } catch (RuntimeException e) {
11843 Slog.w(TAG, "Failure showing dim surface", e);
11844 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011845 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11846 mLastDimWidth = dw;
11847 mLastDimHeight = dh;
11848 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011849 }
11850 }
11851
11852 /**
11853 * Set's the dim surface's layer and update dim parameters that will be used in
11854 * {@link updateSurface} after all windows are examined.
11855 */
11856 void updateParameters(WindowState w, long currentTime) {
11857 mDimSurface.setLayer(w.mAnimLayer-1);
11858
11859 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011860 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011861 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011862 if (mDimTargetAlpha != target) {
11863 // If the desired dim level has changed, then
11864 // start an animation to it.
11865 mLastDimAnimTime = currentTime;
11866 long duration = (w.mAnimating && w.mAnimation != null)
11867 ? w.mAnimation.computeDurationHint()
11868 : DEFAULT_DIM_DURATION;
11869 if (target > mDimTargetAlpha) {
11870 // This is happening behind the activity UI,
11871 // so we can make it run a little longer to
11872 // give a stronger impression without disrupting
11873 // the user.
11874 duration *= DIM_DURATION_MULTIPLIER;
11875 }
11876 if (duration < 1) {
11877 // Don't divide by zero
11878 duration = 1;
11879 }
11880 mDimTargetAlpha = target;
11881 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11882 }
11883 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011884
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011885 /**
11886 * Updating the surface's alpha. Returns true if the animation continues, or returns
11887 * false when the animation is finished and the dim surface is hidden.
11888 */
11889 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11890 if (!dimming) {
11891 if (mDimTargetAlpha != 0) {
11892 mLastDimAnimTime = currentTime;
11893 mDimTargetAlpha = 0;
11894 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11895 }
11896 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011897
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011898 boolean animating = false;
11899 if (mLastDimAnimTime != 0) {
11900 mDimCurrentAlpha += mDimDeltaPerMs
11901 * (currentTime-mLastDimAnimTime);
11902 boolean more = true;
11903 if (displayFrozen) {
11904 // If the display is frozen, there is no reason to animate.
11905 more = false;
11906 } else if (mDimDeltaPerMs > 0) {
11907 if (mDimCurrentAlpha > mDimTargetAlpha) {
11908 more = false;
11909 }
11910 } else if (mDimDeltaPerMs < 0) {
11911 if (mDimCurrentAlpha < mDimTargetAlpha) {
11912 more = false;
11913 }
11914 } else {
11915 more = false;
11916 }
11917
11918 // Do we need to continue animating?
11919 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011920 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011921 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11922 mLastDimAnimTime = currentTime;
11923 mDimSurface.setAlpha(mDimCurrentAlpha);
11924 animating = true;
11925 } else {
11926 mDimCurrentAlpha = mDimTargetAlpha;
11927 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011928 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011929 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11930 mDimSurface.setAlpha(mDimCurrentAlpha);
11931 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011932 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011933 + ": HIDE");
11934 try {
11935 mDimSurface.hide();
11936 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011937 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011938 }
11939 mDimShown = false;
11940 }
11941 }
11942 }
11943 return animating;
11944 }
11945
11946 public void printTo(PrintWriter pw) {
11947 pw.print(" mDimShown="); pw.print(mDimShown);
11948 pw.print(" current="); pw.print(mDimCurrentAlpha);
11949 pw.print(" target="); pw.print(mDimTargetAlpha);
11950 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11951 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11952 }
11953 }
11954
11955 /**
11956 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11957 * This is used for opening/closing transition for apps in compatible mode.
11958 */
11959 private static class FadeInOutAnimation extends Animation {
11960 int mWidth;
11961 boolean mFadeIn;
11962
11963 public FadeInOutAnimation(boolean fadeIn) {
11964 setInterpolator(new AccelerateInterpolator());
11965 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11966 mFadeIn = fadeIn;
11967 }
11968
11969 @Override
11970 protected void applyTransformation(float interpolatedTime, Transformation t) {
11971 float x = interpolatedTime;
11972 if (!mFadeIn) {
11973 x = 1.0f - x; // reverse the interpolation for fade out
11974 }
11975 if (x < 0.5) {
11976 // move the window out of the screen.
11977 t.getMatrix().setTranslate(mWidth, 0);
11978 } else {
11979 t.getMatrix().setTranslate(0, 0);// show
11980 t.setAlpha((x - 0.5f) * 2);
11981 }
11982 }
11983
11984 @Override
11985 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11986 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11987 mWidth = width;
11988 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011989
11990 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011991 public int getZAdjustment() {
11992 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011993 }
11994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995}