blob: 580eea432678ed5fc55e6006f00bbd6c5b9a0816 [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.view.KeyEvent;
107import android.view.MotionEvent;
108import android.view.RawInputEvent;
109import android.view.Surface;
110import android.view.SurfaceSession;
111import android.view.View;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700112import android.view.ViewConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.ViewTreeObserver;
114import android.view.WindowManager;
115import android.view.WindowManagerImpl;
116import android.view.WindowManagerPolicy;
117import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700118import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import android.view.animation.Animation;
120import android.view.animation.AnimationUtils;
121import android.view.animation.Transformation;
122
123import java.io.BufferedWriter;
124import java.io.File;
125import java.io.FileDescriptor;
126import java.io.IOException;
127import java.io.OutputStream;
128import java.io.OutputStreamWriter;
129import java.io.PrintWriter;
130import java.io.StringWriter;
131import java.net.Socket;
132import java.util.ArrayList;
133import java.util.HashMap;
134import java.util.HashSet;
135import java.util.Iterator;
136import java.util.List;
137
138/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700139public class WindowManagerService extends IWindowManager.Stub
140 implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 static final String TAG = "WindowManager";
142 static final boolean DEBUG = false;
143 static final boolean DEBUG_FOCUS = false;
144 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800145 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800146 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static final boolean DEBUG_LAYERS = false;
148 static final boolean DEBUG_INPUT = false;
149 static final boolean DEBUG_INPUT_METHOD = false;
150 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700151 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700153 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_APP_TRANSITIONS = false;
155 static final boolean DEBUG_STARTING_WINDOW = false;
156 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700157 static final boolean DEBUG_WALLPAPER = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700159 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700160 static final boolean MEASURE_LATENCY = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700161 static final boolean ENABLE_NATIVE_INPUT_DISPATCH =
162 WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH;
Michael Chan53071d62009-05-13 17:29:48 -0700163 static private LatencyTimer lt;
164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean PROFILE_ORIENTATION = false;
166 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700167 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 /** How long to wait for subsequent key repeats, in milliseconds */
170 static final int KEY_REPEAT_DELAY = 50;
171
172 /** How much to multiply the policy's type layer, to reserve room
173 * for multiple windows of the same type and Z-ordering adjustment
174 * with TYPE_LAYER_OFFSET. */
175 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
178 * or below others in the same layer. */
179 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 /** How much to increment the layer for each window, to reserve room
182 * for effect surfaces between them.
183 */
184 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 /** The maximum length we will accept for a loaded animation duration:
187 * this is 10 seconds.
188 */
189 static final int MAX_ANIMATION_DURATION = 10*1000;
190
191 /** Amount of time (in milliseconds) to animate the dim surface from one
192 * value to another, when no window animation is driving it.
193 */
194 static final int DEFAULT_DIM_DURATION = 200;
195
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700196 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
197 * compatible windows.
198 */
199 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 /** Adjustment to time to perform a dim, to make it more dramatic.
202 */
203 static final int DIM_DURATION_MULTIPLIER = 6;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700204
205 // Maximum number of milliseconds to wait for input event injection.
206 // FIXME is this value reasonable?
207 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700208
209 // Default input dispatching timeout in nanoseconds.
210 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700211
Dianne Hackborncfaef692009-06-15 14:24:44 -0700212 static final int INJECT_FAILED = 0;
213 static final int INJECT_SUCCEEDED = 1;
214 static final int INJECT_NO_PERMISSION = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 static final int UPDATE_FOCUS_NORMAL = 0;
217 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
218 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
219 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700220
Michael Chane96440f2009-05-06 10:27:36 -0700221 /** The minimum time between dispatching touch events. */
222 int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
223
224 // Last touch event time
225 long mLastTouchEventTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700226
Michael Chane96440f2009-05-06 10:27:36 -0700227 // Last touch event type
228 int mLastTouchEventType = OTHER_EVENT;
Romain Guy06882f82009-06-10 13:36:04 -0700229
Michael Chane96440f2009-05-06 10:27:36 -0700230 // Time to wait before calling useractivity again. This saves CPU usage
231 // when we get a flood of touch events.
232 static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
233
234 // Last time we call user activity
235 long mLastUserActivityCallTime = 0;
236
Romain Guy06882f82009-06-10 13:36:04 -0700237 // Last time we updated battery stats
Michael Chane96440f2009-05-06 10:27:36 -0700238 long mLastBatteryStatsCallTime = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700241 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
243 /**
244 * Condition waited on by {@link #reenableKeyguard} to know the call to
245 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500246 * This is set to true only if mKeyguardTokenWatcher.acquired() has
247 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500249 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
Jim Miller284b62e2010-06-08 14:27:42 -0700251 private static final int ALLOW_DISABLE_YES = 1;
252 private static final int ALLOW_DISABLE_NO = 0;
253 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
254 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
255
Mike Lockwood983ee092009-11-22 01:42:24 -0500256 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
257 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700259 if (shouldAllowDisableKeyguard()) {
260 mPolicy.enableKeyguard(false);
261 mKeyguardDisabled = true;
262 } else {
263 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
266 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700267 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500268 synchronized (mKeyguardTokenWatcher) {
269 mKeyguardDisabled = false;
270 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 }
272 }
273 };
274
Jim Miller284b62e2010-06-08 14:27:42 -0700275 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
276 @Override
277 public void onReceive(Context context, Intent intent) {
278 mPolicy.enableKeyguard(true);
279 synchronized(mKeyguardTokenWatcher) {
280 // lazily evaluate this next time we're asked to disable keyguard
281 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
282 mKeyguardDisabled = false;
283 }
284 }
285 };
286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 final Context mContext;
288
289 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
294
295 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 /**
300 * All currently active sessions with clients.
301 */
302 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 /**
305 * Mapping from an IWindow IBinder to the server's Window object.
306 * This is also used as the lock for all of our state.
307 */
308 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
309
310 /**
311 * Mapping from a token IBinder to a WindowToken object.
312 */
313 final HashMap<IBinder, WindowToken> mTokenMap =
314 new HashMap<IBinder, WindowToken>();
315
316 /**
317 * The same tokens as mTokenMap, stored in a list for efficient iteration
318 * over them.
319 */
320 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 /**
323 * Window tokens that are in the process of exiting, but still
324 * on screen for animations.
325 */
326 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
327
328 /**
329 * Z-ordered (bottom-most first) list of all application tokens, for
330 * controlling the ordering of windows in different applications. This
331 * contains WindowToken objects.
332 */
333 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
334
335 /**
336 * Application tokens that are in the process of exiting, but still
337 * on screen for animations.
338 */
339 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
340
341 /**
342 * List of window tokens that have finished starting their application,
343 * and now need to have the policy remove their windows.
344 */
345 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
346
347 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700348 * This was the app token that was used to retrieve the last enter
349 * animation. It will be used for the next exit animation.
350 */
351 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800352
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700353 /**
354 * These were the layout params used to retrieve the last enter animation.
355 * They will be used for the next exit animation.
356 */
357 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800358
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700359 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 * Z-ordered (bottom-most first) list of all Window objects.
361 */
362 final ArrayList mWindows = new ArrayList();
363
364 /**
365 * Windows that are being resized. Used so we can tell the client about
366 * the resize after closing the transaction in which we resized the
367 * underlying surface.
368 */
369 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
370
371 /**
372 * Windows whose animations have ended and now must be removed.
373 */
374 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
375
376 /**
377 * Windows whose surface should be destroyed.
378 */
379 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
380
381 /**
382 * Windows that have lost input focus and are waiting for the new
383 * focus window to be displayed before they are told about this.
384 */
385 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
386
387 /**
388 * This is set when we have run out of memory, and will either be an empty
389 * list or contain windows that need to be force removed.
390 */
391 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700396 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 Surface mBlurSurface;
398 boolean mBlurShown;
Romain Guy06882f82009-06-10 13:36:04 -0700399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 final float[] mTmpFloats = new float[9];
403
404 boolean mSafeMode;
405 boolean mDisplayEnabled = false;
406 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700407 int mInitialDisplayWidth = 0;
408 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 int mRotation = 0;
410 int mRequestedRotation = 0;
411 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700412 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 ArrayList<IRotationWatcher> mRotationWatchers
414 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 boolean mLayoutNeeded = true;
417 boolean mAnimationPending = false;
418 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800419 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 boolean mWindowsFreezingScreen = false;
421 long mFreezeGcPending = 0;
422 int mAppsFreezingScreen = 0;
423
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800424 int mLayoutSeq = 0;
425
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800426 // State while inside of layoutAndPlaceSurfacesLocked().
427 boolean mFocusMayChange;
428
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800429 Configuration mCurConfiguration = new Configuration();
430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 // This is held as long as we have the screen frozen, to give us time to
432 // perform a rotation animation when turning off shows the lock screen which
433 // changes the orientation.
434 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 // State management of app transitions. When we are preparing for a
437 // transition, mNextAppTransition will be the kind of transition to
438 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
439 // mOpeningApps and mClosingApps are the lists of tokens that will be
440 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700441 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700442 String mNextAppTransitionPackage;
443 int mNextAppTransitionEnter;
444 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700446 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 boolean mAppTransitionTimeout = false;
448 boolean mStartingIconInTransition = false;
449 boolean mSkipAppTransitionAnimation = false;
450 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
451 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700452 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
453 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 H mH = new H();
458
459 WindowState mCurrentFocus = null;
460 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 // This just indicates the window the input method is on top of, not
463 // necessarily the window its input is going to.
464 WindowState mInputMethodTarget = null;
465 WindowState mUpcomingInputMethodTarget = null;
466 boolean mInputMethodTargetWaitingAnim;
467 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 WindowState mInputMethodWindow = null;
470 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
471
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700472 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800473
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700474 // If non-null, this is the currently visible window that is associated
475 // with the wallpaper.
476 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700477 // If non-null, we are in the middle of animating from one wallpaper target
478 // to another, and this is the lower one in Z-order.
479 WindowState mLowerWallpaperTarget = null;
480 // If non-null, we are in the middle of animating from one wallpaper target
481 // to another, and this is the higher one in Z-order.
482 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700483 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700484 float mLastWallpaperX = -1;
485 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800486 float mLastWallpaperXStep = -1;
487 float mLastWallpaperYStep = -1;
Dianne Hackborn6adba242009-11-10 11:10:09 -0800488 boolean mSendingPointersToWallpaper = false;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700489 // This is set when we are waiting for a wallpaper to tell us it is done
490 // changing its scroll position.
491 WindowState mWaitingOnWallpaper;
492 // The last time we had a timeout when waiting for a wallpaper.
493 long mLastWallpaperTimeoutTime;
494 // We give a wallpaper up to 150ms to finish scrolling.
495 static final long WALLPAPER_TIMEOUT = 150;
496 // Time we wait after a timeout before trying to wait again.
497 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 AppWindowToken mFocusedApp = null;
500
501 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 float mWindowAnimationScale = 1.0f;
504 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 final KeyWaiter mKeyWaiter = new KeyWaiter();
507 final KeyQ mQueue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700508 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 final InputDispatcherThread mInputThread;
510
511 // Who is holding the screen on.
512 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700513 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700514
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700515 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 /**
518 * Whether the UI is currently running in touch mode (not showing
519 * navigational focus because the user is directly pressing the screen).
520 */
521 boolean mInTouchMode = false;
522
523 private ViewServer mViewServer;
524
525 final Rect mTempRect = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -0700526
Dianne Hackbornc485a602009-03-24 22:39:49 -0700527 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700528 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700529
530 // The frame use to limit the size of the app running in compatibility mode.
531 Rect mCompatibleScreenFrame = new Rect();
532 // The surface used to fill the outer rim of the app running in compatibility mode.
533 Surface mBackgroundFillerSurface = null;
534 boolean mBackgroundFillerShown = false;
535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 public static WindowManagerService main(Context context,
537 PowerManagerService pm, boolean haveInputMethods) {
538 WMThread thr = new WMThread(context, pm, haveInputMethods);
539 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 synchronized (thr) {
542 while (thr.mService == null) {
543 try {
544 thr.wait();
545 } catch (InterruptedException e) {
546 }
547 }
548 }
Romain Guy06882f82009-06-10 13:36:04 -0700549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 return thr.mService;
551 }
Romain Guy06882f82009-06-10 13:36:04 -0700552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 static class WMThread extends Thread {
554 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 private final Context mContext;
557 private final PowerManagerService mPM;
558 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 public WMThread(Context context, PowerManagerService pm,
561 boolean haveInputMethods) {
562 super("WindowManager");
563 mContext = context;
564 mPM = pm;
565 mHaveInputMethods = haveInputMethods;
566 }
Romain Guy06882f82009-06-10 13:36:04 -0700567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 public void run() {
569 Looper.prepare();
570 WindowManagerService s = new WindowManagerService(mContext, mPM,
571 mHaveInputMethods);
572 android.os.Process.setThreadPriority(
573 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700574 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 synchronized (this) {
577 mService = s;
578 notifyAll();
579 }
Romain Guy06882f82009-06-10 13:36:04 -0700580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 Looper.loop();
582 }
583 }
584
585 static class PolicyThread extends Thread {
586 private final WindowManagerPolicy mPolicy;
587 private final WindowManagerService mService;
588 private final Context mContext;
589 private final PowerManagerService mPM;
590 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 public PolicyThread(WindowManagerPolicy policy,
593 WindowManagerService service, Context context,
594 PowerManagerService pm) {
595 super("WindowManagerPolicy");
596 mPolicy = policy;
597 mService = service;
598 mContext = context;
599 mPM = pm;
600 }
Romain Guy06882f82009-06-10 13:36:04 -0700601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 public void run() {
603 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800604 WindowManagerPolicyThread.set(this, Looper.myLooper());
605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800607 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 android.os.Process.setThreadPriority(
609 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700610 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 synchronized (this) {
614 mRunning = true;
615 notifyAll();
616 }
Romain Guy06882f82009-06-10 13:36:04 -0700617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 Looper.loop();
619 }
620 }
621
622 private WindowManagerService(Context context, PowerManagerService pm,
623 boolean haveInputMethods) {
Michael Chan53071d62009-05-13 17:29:48 -0700624 if (MEASURE_LATENCY) {
625 lt = new LatencyTimer(100, 1000);
626 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 mContext = context;
629 mHaveInputMethods = haveInputMethods;
630 mLimitedAlphaCompositing = context.getResources().getBoolean(
631 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 mPowerManager = pm;
634 mPowerManager.setPolicy(mPolicy);
635 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
636 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
637 "SCREEN_FROZEN");
638 mScreenFrozenLock.setReferenceCounted(false);
639
640 mActivityManager = ActivityManagerNative.getDefault();
641 mBatteryStats = BatteryStatsService.getService();
642
643 // Get persisted window scale setting
644 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
645 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
646 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
647 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700648
Jim Miller284b62e2010-06-08 14:27:42 -0700649 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
650 IntentFilter filter = new IntentFilter();
651 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
652 mContext.registerReceiver(mBroadcastReceiver, filter);
653
Michael Chan9f028e62009-08-04 17:37:46 -0700654 int max_events_per_sec = 35;
655 try {
656 max_events_per_sec = Integer.parseInt(SystemProperties
657 .get("windowsmgr.max_events_per_sec"));
658 if (max_events_per_sec < 1) {
659 max_events_per_sec = 35;
660 }
661 } catch (NumberFormatException e) {
662 }
663 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
664
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700665 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
666 "KEEP_SCREEN_ON_FLAG");
667 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700669 if (ENABLE_NATIVE_INPUT_DISPATCH) {
670 mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager);
671 } else {
672 mInputManager = null;
673 }
674 mQueue = new KeyQ();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 mInputThread = new InputDispatcherThread();
Romain Guy06882f82009-06-10 13:36:04 -0700676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
678 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 synchronized (thr) {
681 while (!thr.mRunning) {
682 try {
683 thr.wait();
684 } catch (InterruptedException e) {
685 }
686 }
687 }
Romain Guy06882f82009-06-10 13:36:04 -0700688
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700689 if (ENABLE_NATIVE_INPUT_DISPATCH) {
690 mInputManager.start();
691 } else {
692 mInputThread.start();
693 }
Romain Guy06882f82009-06-10 13:36:04 -0700694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 // Add ourself to the Watchdog monitors.
696 Watchdog.getInstance().addMonitor(this);
697 }
698
699 @Override
700 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
701 throws RemoteException {
702 try {
703 return super.onTransact(code, data, reply, flags);
704 } catch (RuntimeException e) {
705 // The window manager only throws security exceptions, so let's
706 // log all others.
707 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800708 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709 }
710 throw e;
711 }
712 }
713
714 private void placeWindowAfter(Object pos, WindowState window) {
715 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800716 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 TAG, "Adding window " + window + " at "
718 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
719 mWindows.add(i+1, window);
720 }
721
722 private void placeWindowBefore(Object pos, WindowState window) {
723 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800724 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 TAG, "Adding window " + window + " at "
726 + i + " of " + mWindows.size() + " (before " + pos + ")");
727 mWindows.add(i, window);
728 }
729
730 //This method finds out the index of a window that has the same app token as
731 //win. used for z ordering the windows in mWindows
732 private int findIdxBasedOnAppTokens(WindowState win) {
733 //use a local variable to cache mWindows
734 ArrayList localmWindows = mWindows;
735 int jmax = localmWindows.size();
736 if(jmax == 0) {
737 return -1;
738 }
739 for(int j = (jmax-1); j >= 0; j--) {
740 WindowState wentry = (WindowState)localmWindows.get(j);
741 if(wentry.mAppToken == win.mAppToken) {
742 return j;
743 }
744 }
745 return -1;
746 }
Romain Guy06882f82009-06-10 13:36:04 -0700747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
749 final IWindow client = win.mClient;
750 final WindowToken token = win.mToken;
751 final ArrayList localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 final int N = localmWindows.size();
754 final WindowState attached = win.mAttachedWindow;
755 int i;
756 if (attached == null) {
757 int tokenWindowsPos = token.windows.size();
758 if (token.appWindowToken != null) {
759 int index = tokenWindowsPos-1;
760 if (index >= 0) {
761 // If this application has existing windows, we
762 // simply place the new window on top of them... but
763 // keep the starting window on top.
764 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
765 // Base windows go behind everything else.
766 placeWindowBefore(token.windows.get(0), win);
767 tokenWindowsPos = 0;
768 } else {
769 AppWindowToken atoken = win.mAppToken;
770 if (atoken != null &&
771 token.windows.get(index) == atoken.startingWindow) {
772 placeWindowBefore(token.windows.get(index), win);
773 tokenWindowsPos--;
774 } else {
775 int newIdx = findIdxBasedOnAppTokens(win);
776 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700777 //there is a window above this one associated with the same
778 //apptoken note that the window could be a floating window
779 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800781 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700782 TAG, "Adding window " + win + " at "
783 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 localmWindows.add(newIdx+1, win);
Romain Guy06882f82009-06-10 13:36:04 -0700785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 }
787 }
788 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800789 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 TAG, "Figuring out where to add app window "
791 + client.asBinder() + " (token=" + token + ")");
792 // Figure out where the window should go, based on the
793 // order of applications.
794 final int NA = mAppTokens.size();
795 Object pos = null;
796 for (i=NA-1; i>=0; i--) {
797 AppWindowToken t = mAppTokens.get(i);
798 if (t == token) {
799 i--;
800 break;
801 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800802
Dianne Hackborna8f60182009-09-01 19:01:50 -0700803 // We haven't reached the token yet; if this token
804 // is not going to the bottom and has windows, we can
805 // use it as an anchor for when we do reach the token.
806 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 pos = t.windows.get(0);
808 }
809 }
810 // We now know the index into the apps. If we found
811 // an app window above, that gives us the position; else
812 // we need to look some more.
813 if (pos != null) {
814 // Move behind any windows attached to this one.
Romain Guy06882f82009-06-10 13:36:04 -0700815 WindowToken atoken =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 mTokenMap.get(((WindowState)pos).mClient.asBinder());
817 if (atoken != null) {
818 final int NC = atoken.windows.size();
819 if (NC > 0) {
820 WindowState bottom = atoken.windows.get(0);
821 if (bottom.mSubLayer < 0) {
822 pos = bottom;
823 }
824 }
825 }
826 placeWindowBefore(pos, win);
827 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700828 // Continue looking down until we find the first
829 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 while (i >= 0) {
831 AppWindowToken t = mAppTokens.get(i);
832 final int NW = t.windows.size();
833 if (NW > 0) {
834 pos = t.windows.get(NW-1);
835 break;
836 }
837 i--;
838 }
839 if (pos != null) {
840 // Move in front of any windows attached to this
841 // one.
842 WindowToken atoken =
843 mTokenMap.get(((WindowState)pos).mClient.asBinder());
844 if (atoken != null) {
845 final int NC = atoken.windows.size();
846 if (NC > 0) {
847 WindowState top = atoken.windows.get(NC-1);
848 if (top.mSubLayer >= 0) {
849 pos = top;
850 }
851 }
852 }
853 placeWindowAfter(pos, win);
854 } else {
855 // Just search for the start of this layer.
856 final int myLayer = win.mBaseLayer;
857 for (i=0; i<N; i++) {
858 WindowState w = (WindowState)localmWindows.get(i);
859 if (w.mBaseLayer > myLayer) {
860 break;
861 }
862 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700864 TAG, "Adding window " + win + " at "
865 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 localmWindows.add(i, win);
867 }
868 }
869 }
870 } else {
871 // Figure out where window should go, based on layer.
872 final int myLayer = win.mBaseLayer;
873 for (i=N-1; i>=0; i--) {
874 if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
875 i++;
876 break;
877 }
878 }
879 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800880 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700881 TAG, "Adding window " + win + " at "
882 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 localmWindows.add(i, win);
884 }
885 if (addToToken) {
886 token.windows.add(tokenWindowsPos, win);
887 }
888
889 } else {
890 // Figure out this window's ordering relative to the window
891 // it is attached to.
892 final int NA = token.windows.size();
893 final int sublayer = win.mSubLayer;
894 int largestSublayer = Integer.MIN_VALUE;
895 WindowState windowWithLargestSublayer = null;
896 for (i=0; i<NA; i++) {
897 WindowState w = token.windows.get(i);
898 final int wSublayer = w.mSubLayer;
899 if (wSublayer >= largestSublayer) {
900 largestSublayer = wSublayer;
901 windowWithLargestSublayer = w;
902 }
903 if (sublayer < 0) {
904 // For negative sublayers, we go below all windows
905 // in the same sublayer.
906 if (wSublayer >= sublayer) {
907 if (addToToken) {
908 token.windows.add(i, win);
909 }
910 placeWindowBefore(
911 wSublayer >= 0 ? attached : w, win);
912 break;
913 }
914 } else {
915 // For positive sublayers, we go above all windows
916 // in the same sublayer.
917 if (wSublayer > sublayer) {
918 if (addToToken) {
919 token.windows.add(i, win);
920 }
921 placeWindowBefore(w, win);
922 break;
923 }
924 }
925 }
926 if (i >= NA) {
927 if (addToToken) {
928 token.windows.add(win);
929 }
930 if (sublayer < 0) {
931 placeWindowBefore(attached, win);
932 } else {
933 placeWindowAfter(largestSublayer >= 0
934 ? windowWithLargestSublayer
935 : attached,
936 win);
937 }
938 }
939 }
Romain Guy06882f82009-06-10 13:36:04 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 if (win.mAppToken != null && addToToken) {
942 win.mAppToken.allAppWindows.add(win);
943 }
944 }
Romain Guy06882f82009-06-10 13:36:04 -0700945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 static boolean canBeImeTarget(WindowState w) {
947 final int fl = w.mAttrs.flags
948 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
949 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
950 return w.isVisibleOrAdding();
951 }
952 return false;
953 }
Romain Guy06882f82009-06-10 13:36:04 -0700954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
956 final ArrayList localmWindows = mWindows;
957 final int N = localmWindows.size();
958 WindowState w = null;
959 int i = N;
960 while (i > 0) {
961 i--;
962 w = (WindowState)localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -0700963
Joe Onorato8a9b2202010-02-26 18:56:32 -0800964 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 // + Integer.toHexString(w.mAttrs.flags));
966 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800967 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -0700968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 // Yet more tricksyness! If this window is a "starting"
970 // window, we do actually want to be on top of it, but
971 // it is not -really- where input will go. So if the caller
972 // is not actually looking to move the IME, look down below
973 // for a real window to target...
974 if (!willMove
975 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
976 && i > 0) {
977 WindowState wb = (WindowState)localmWindows.get(i-1);
978 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
979 i--;
980 w = wb;
981 }
982 }
983 break;
984 }
985 }
Romain Guy06882f82009-06-10 13:36:04 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -0700988
Joe Onorato8a9b2202010-02-26 18:56:32 -0800989 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -0700991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 if (willMove && w != null) {
993 final WindowState curTarget = mInputMethodTarget;
994 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -0700995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 // Now some fun for dealing with window animations that
997 // modify the Z order. We need to look at all windows below
998 // the current target that are in this app, finding the highest
999 // visible one in layering.
1000 AppWindowToken token = curTarget.mAppToken;
1001 WindowState highestTarget = null;
1002 int highestPos = 0;
1003 if (token.animating || token.animation != null) {
1004 int pos = 0;
1005 pos = localmWindows.indexOf(curTarget);
1006 while (pos >= 0) {
1007 WindowState win = (WindowState)localmWindows.get(pos);
1008 if (win.mAppToken != token) {
1009 break;
1010 }
1011 if (!win.mRemoved) {
1012 if (highestTarget == null || win.mAnimLayer >
1013 highestTarget.mAnimLayer) {
1014 highestTarget = win;
1015 highestPos = pos;
1016 }
1017 }
1018 pos--;
1019 }
1020 }
Romain Guy06882f82009-06-10 13:36:04 -07001021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001023 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 + mNextAppTransition + " " + highestTarget
1025 + " animating=" + highestTarget.isAnimating()
1026 + " layer=" + highestTarget.mAnimLayer
1027 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001028
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001029 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 // If we are currently setting up for an animation,
1031 // hold everything until we can find out what will happen.
1032 mInputMethodTargetWaitingAnim = true;
1033 mInputMethodTarget = highestTarget;
1034 return highestPos + 1;
1035 } else if (highestTarget.isAnimating() &&
1036 highestTarget.mAnimLayer > w.mAnimLayer) {
1037 // If the window we are currently targeting is involved
1038 // with an animation, and it is on top of the next target
1039 // we will be over, then hold off on moving until
1040 // that is done.
1041 mInputMethodTarget = highestTarget;
1042 return highestPos + 1;
1043 }
1044 }
1045 }
1046 }
Romain Guy06882f82009-06-10 13:36:04 -07001047
Joe Onorato8a9b2202010-02-26 18:56:32 -08001048 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 if (w != null) {
1050 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001051 if (DEBUG_INPUT_METHOD) {
1052 RuntimeException e = null;
1053 if (!HIDE_STACK_CRAWLS) {
1054 e = new RuntimeException();
1055 e.fillInStackTrace();
1056 }
1057 Slog.w(TAG, "Moving IM target from "
1058 + mInputMethodTarget + " to " + w, e);
1059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 mInputMethodTarget = w;
1061 if (w.mAppToken != null) {
1062 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1063 } else {
1064 setInputMethodAnimLayerAdjustment(0);
1065 }
1066 }
1067 return i+1;
1068 }
1069 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001070 if (DEBUG_INPUT_METHOD) {
1071 RuntimeException e = null;
1072 if (!HIDE_STACK_CRAWLS) {
1073 e = new RuntimeException();
1074 e.fillInStackTrace();
1075 }
1076 Slog.w(TAG, "Moving IM target from "
1077 + mInputMethodTarget + " to null", e);
1078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 mInputMethodTarget = null;
1080 setInputMethodAnimLayerAdjustment(0);
1081 }
1082 return -1;
1083 }
Romain Guy06882f82009-06-10 13:36:04 -07001084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 void addInputMethodWindowToListLocked(WindowState win) {
1086 int pos = findDesiredInputMethodWindowIndexLocked(true);
1087 if (pos >= 0) {
1088 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001089 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001090 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 mWindows.add(pos, win);
1092 moveInputMethodDialogsLocked(pos+1);
1093 return;
1094 }
1095 win.mTargetAppToken = null;
1096 addWindowToListInOrderLocked(win, true);
1097 moveInputMethodDialogsLocked(pos);
1098 }
Romain Guy06882f82009-06-10 13:36:04 -07001099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001101 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 mInputMethodAnimLayerAdjustment = adj;
1103 WindowState imw = mInputMethodWindow;
1104 if (imw != null) {
1105 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001106 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 + " anim layer: " + imw.mAnimLayer);
1108 int wi = imw.mChildWindows.size();
1109 while (wi > 0) {
1110 wi--;
1111 WindowState cw = (WindowState)imw.mChildWindows.get(wi);
1112 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001113 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 + " anim layer: " + cw.mAnimLayer);
1115 }
1116 }
1117 int di = mInputMethodDialogs.size();
1118 while (di > 0) {
1119 di --;
1120 imw = mInputMethodDialogs.get(di);
1121 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001122 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 + " anim layer: " + imw.mAnimLayer);
1124 }
1125 }
Romain Guy06882f82009-06-10 13:36:04 -07001126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1128 int wpos = mWindows.indexOf(win);
1129 if (wpos >= 0) {
1130 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001131 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 mWindows.remove(wpos);
1133 int NC = win.mChildWindows.size();
1134 while (NC > 0) {
1135 NC--;
1136 WindowState cw = (WindowState)win.mChildWindows.get(NC);
1137 int cpos = mWindows.indexOf(cw);
1138 if (cpos >= 0) {
1139 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001140 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001141 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 mWindows.remove(cpos);
1143 }
1144 }
1145 }
1146 return interestingPos;
1147 }
Romain Guy06882f82009-06-10 13:36:04 -07001148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 private void reAddWindowToListInOrderLocked(WindowState win) {
1150 addWindowToListInOrderLocked(win, false);
1151 // This is a hack to get all of the child windows added as well
1152 // at the right position. Child windows should be rare and
1153 // this case should be rare, so it shouldn't be that big a deal.
1154 int wpos = mWindows.indexOf(win);
1155 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001156 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001157 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 mWindows.remove(wpos);
1159 reAddWindowLocked(wpos, win);
1160 }
1161 }
Romain Guy06882f82009-06-10 13:36:04 -07001162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 void logWindowList(String prefix) {
1164 int N = mWindows.size();
1165 while (N > 0) {
1166 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001167 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 }
1169 }
Romain Guy06882f82009-06-10 13:36:04 -07001170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 void moveInputMethodDialogsLocked(int pos) {
1172 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001175 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 for (int i=0; i<N; i++) {
1177 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1178 }
1179 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001180 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 logWindowList(" ");
1182 }
Romain Guy06882f82009-06-10 13:36:04 -07001183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 if (pos >= 0) {
1185 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1186 if (pos < mWindows.size()) {
1187 WindowState wp = (WindowState)mWindows.get(pos);
1188 if (wp == mInputMethodWindow) {
1189 pos++;
1190 }
1191 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001192 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 for (int i=0; i<N; i++) {
1194 WindowState win = dialogs.get(i);
1195 win.mTargetAppToken = targetAppToken;
1196 pos = reAddWindowLocked(pos, win);
1197 }
1198 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001199 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 logWindowList(" ");
1201 }
1202 return;
1203 }
1204 for (int i=0; i<N; i++) {
1205 WindowState win = dialogs.get(i);
1206 win.mTargetAppToken = null;
1207 reAddWindowToListInOrderLocked(win);
1208 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001209 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 logWindowList(" ");
1211 }
1212 }
1213 }
Romain Guy06882f82009-06-10 13:36:04 -07001214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1216 final WindowState imWin = mInputMethodWindow;
1217 final int DN = mInputMethodDialogs.size();
1218 if (imWin == null && DN == 0) {
1219 return false;
1220 }
Romain Guy06882f82009-06-10 13:36:04 -07001221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1223 if (imPos >= 0) {
1224 // In this case, the input method windows are to be placed
1225 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 // First check to see if the input method windows are already
1228 // located here, and contiguous.
1229 final int N = mWindows.size();
1230 WindowState firstImWin = imPos < N
1231 ? (WindowState)mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 // Figure out the actual input method window that should be
1234 // at the bottom of their stack.
1235 WindowState baseImWin = imWin != null
1236 ? imWin : mInputMethodDialogs.get(0);
1237 if (baseImWin.mChildWindows.size() > 0) {
1238 WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
1239 if (cw.mSubLayer < 0) baseImWin = cw;
1240 }
Romain Guy06882f82009-06-10 13:36:04 -07001241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 if (firstImWin == baseImWin) {
1243 // The windows haven't moved... but are they still contiguous?
1244 // First find the top IM window.
1245 int pos = imPos+1;
1246 while (pos < N) {
1247 if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
1248 break;
1249 }
1250 pos++;
1251 }
1252 pos++;
1253 // Now there should be no more input method windows above.
1254 while (pos < N) {
1255 if (((WindowState)mWindows.get(pos)).mIsImWindow) {
1256 break;
1257 }
1258 pos++;
1259 }
1260 if (pos >= N) {
1261 // All is good!
1262 return false;
1263 }
1264 }
Romain Guy06882f82009-06-10 13:36:04 -07001265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 if (imWin != null) {
1267 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001268 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 logWindowList(" ");
1270 }
1271 imPos = tmpRemoveWindowLocked(imPos, imWin);
1272 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001273 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 logWindowList(" ");
1275 }
1276 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1277 reAddWindowLocked(imPos, imWin);
1278 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001279 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 logWindowList(" ");
1281 }
1282 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1283 } else {
1284 moveInputMethodDialogsLocked(imPos);
1285 }
Romain Guy06882f82009-06-10 13:36:04 -07001286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 } else {
1288 // In this case, the input method windows go in a fixed layer,
1289 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001292 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 tmpRemoveWindowLocked(0, imWin);
1294 imWin.mTargetAppToken = null;
1295 reAddWindowToListInOrderLocked(imWin);
1296 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001297 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 logWindowList(" ");
1299 }
1300 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1301 } else {
1302 moveInputMethodDialogsLocked(-1);;
1303 }
Romain Guy06882f82009-06-10 13:36:04 -07001304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
Romain Guy06882f82009-06-10 13:36:04 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 if (needAssignLayers) {
1308 assignLayersLocked();
1309 }
Romain Guy06882f82009-06-10 13:36:04 -07001310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 return true;
1312 }
Romain Guy06882f82009-06-10 13:36:04 -07001313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 void adjustInputMethodDialogsLocked() {
1315 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1316 }
Romain Guy06882f82009-06-10 13:36:04 -07001317
Dianne Hackborn25994b42009-09-04 14:21:19 -07001318 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001319 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001320 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1321 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1322 ? wallpaperTarget.mAppToken.animation : null)
1323 + " upper=" + mUpperWallpaperTarget
1324 + " lower=" + mLowerWallpaperTarget);
1325 return (wallpaperTarget != null
1326 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1327 && wallpaperTarget.mAppToken.animation != null)))
1328 || mUpperWallpaperTarget != null
1329 || mLowerWallpaperTarget != null;
1330 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001331
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001332 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1333 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001334
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001335 int adjustWallpaperWindowsLocked() {
1336 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001337
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001338 final int dw = mDisplay.getWidth();
1339 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001340
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001341 // First find top-most window that has asked to be on top of the
1342 // wallpaper; all wallpapers go behind it.
1343 final ArrayList localmWindows = mWindows;
1344 int N = localmWindows.size();
1345 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001346 WindowState foundW = null;
1347 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001348 WindowState topCurW = null;
1349 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001350 int i = N;
1351 while (i > 0) {
1352 i--;
1353 w = (WindowState)localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001354 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1355 if (topCurW == null) {
1356 topCurW = w;
1357 topCurI = i;
1358 }
1359 continue;
1360 }
1361 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001362 if (w.mAppToken != null) {
1363 // If this window's app token is hidden and not animating,
1364 // it is of no interest to us.
1365 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001366 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001367 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001368 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001369 continue;
1370 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001371 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001372 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001373 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1374 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001375 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001376 && (mWallpaperTarget == w
1377 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001378 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001379 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001380 foundW = w;
1381 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001382 if (w == mWallpaperTarget && ((w.mAppToken != null
1383 && w.mAppToken.animation != null)
1384 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001385 // The current wallpaper target is animating, so we'll
1386 // look behind it for another possible target and figure
1387 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001388 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001389 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001390 continue;
1391 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001392 break;
1393 }
1394 }
1395
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001396 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001397 // If we are currently waiting for an app transition, and either
1398 // the current target or the next target are involved with it,
1399 // then hold off on doing anything with the wallpaper.
1400 // Note that we are checking here for just whether the target
1401 // is part of an app token... which is potentially overly aggressive
1402 // (the app token may not be involved in the transition), but good
1403 // enough (we'll just wait until whatever transition is pending
1404 // executes).
1405 if (mWallpaperTarget != null && mWallpaperTarget.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 current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001408 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001409 }
1410 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001411 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001412 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001413 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001414 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001415 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001416
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001417 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001418 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001419 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001420 + " oldTarget: " + mWallpaperTarget);
1421 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001422
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001423 mLowerWallpaperTarget = null;
1424 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001425
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001426 WindowState oldW = mWallpaperTarget;
1427 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001428
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001429 // Now what is happening... if the current and new targets are
1430 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001431 if (foundW != null && oldW != null) {
1432 boolean oldAnim = oldW.mAnimation != null
1433 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1434 boolean foundAnim = foundW.mAnimation != null
1435 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001436 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001438 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001439 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001440 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001441 int oldI = localmWindows.indexOf(oldW);
1442 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001443 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001444 }
1445 if (oldI >= 0) {
1446 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001447 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001448 + "=" + oldW + "; new#" + foundI
1449 + "=" + foundW);
1450 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001451
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001452 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001453 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001454 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001456 }
1457 mWallpaperTarget = oldW;
1458 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001459
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001460 // Now set the upper and lower wallpaper targets
1461 // correctly, and make sure that we are positioning
1462 // the wallpaper below the lower.
1463 if (foundI > oldI) {
1464 // The new target is on top of the old one.
1465 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001466 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001467 }
1468 mUpperWallpaperTarget = foundW;
1469 mLowerWallpaperTarget = oldW;
1470 foundW = oldW;
1471 foundI = oldI;
1472 } else {
1473 // The new target is below the old one.
1474 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001476 }
1477 mUpperWallpaperTarget = oldW;
1478 mLowerWallpaperTarget = foundW;
1479 }
1480 }
1481 }
1482 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001483
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001484 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001485 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001486 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1487 || (mLowerWallpaperTarget.mAppToken != null
1488 && mLowerWallpaperTarget.mAppToken.animation != null);
1489 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1490 || (mUpperWallpaperTarget.mAppToken != null
1491 && mUpperWallpaperTarget.mAppToken.animation != null);
1492 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001493 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001494 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001495 }
1496 mLowerWallpaperTarget = null;
1497 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001498 }
1499 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001500
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001501 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001502 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001503 // The window is visible to the compositor... but is it visible
1504 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001505 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001506 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001507
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001508 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001509 // its layer adjustment. Only do this if we are not transfering
1510 // between two wallpaper targets.
1511 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001512 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001513 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001514
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001515 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1516 * TYPE_LAYER_MULTIPLIER
1517 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001518
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001519 // Now w is the window we are supposed to be behind... but we
1520 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001521 // AND any starting window associated with it, AND below the
1522 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001523 while (foundI > 0) {
1524 WindowState wb = (WindowState)localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001525 if (wb.mBaseLayer < maxLayer &&
1526 wb.mAttachedWindow != foundW &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001527 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001528 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001529 // This window is not related to the previous one in any
1530 // interesting way, so stop here.
1531 break;
1532 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001533 foundW = wb;
1534 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001535 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001536 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001537 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001538 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001539
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001540 if (foundW == null && topCurW != null) {
1541 // There is no wallpaper target, so it goes at the bottom.
1542 // We will assume it is the same place as last time, if known.
1543 foundW = topCurW;
1544 foundI = topCurI+1;
1545 } else {
1546 // Okay i is the position immediately above the wallpaper. Look at
1547 // what is below it for later.
1548 foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
1549 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001550
Dianne Hackborn284ac932009-08-28 10:34:25 -07001551 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001552 if (mWallpaperTarget.mWallpaperX >= 0) {
1553 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001554 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001555 }
1556 if (mWallpaperTarget.mWallpaperY >= 0) {
1557 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001558 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001559 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001560 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001561
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001562 // Start stepping backwards from here, ensuring that our wallpaper windows
1563 // are correctly placed.
1564 int curTokenIndex = mWallpaperTokens.size();
1565 while (curTokenIndex > 0) {
1566 curTokenIndex--;
1567 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001568 if (token.hidden == visible) {
1569 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1570 token.hidden = !visible;
1571 // Need to do a layout to ensure the wallpaper now has the
1572 // correct size.
1573 mLayoutNeeded = true;
1574 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001575
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001576 int curWallpaperIndex = token.windows.size();
1577 while (curWallpaperIndex > 0) {
1578 curWallpaperIndex--;
1579 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001580
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001581 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001582 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001583 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001584
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001585 // First, make sure the client has the current visibility
1586 // state.
1587 if (wallpaper.mWallpaperVisible != visible) {
1588 wallpaper.mWallpaperVisible = visible;
1589 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001590 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001591 "Setting visibility of wallpaper " + wallpaper
1592 + ": " + visible);
1593 wallpaper.mClient.dispatchAppVisibility(visible);
1594 } catch (RemoteException e) {
1595 }
1596 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001597
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001598 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001599 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001600 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001601
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001602 // First, if this window is at the current index, then all
1603 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001604 if (wallpaper == foundW) {
1605 foundI--;
1606 foundW = foundI > 0
1607 ? (WindowState)localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001608 continue;
1609 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001610
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001611 // The window didn't match... the current wallpaper window,
1612 // wherever it is, is in the wrong place, so make sure it is
1613 // not in the list.
1614 int oldIndex = localmWindows.indexOf(wallpaper);
1615 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001616 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001617 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001618 localmWindows.remove(oldIndex);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001619 if (oldIndex < foundI) {
1620 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001621 }
1622 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001623
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001624 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001625 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001626 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001627 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001628
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001629 localmWindows.add(foundI, wallpaper);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001630 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001631 }
1632 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001633
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001634 return changed;
1635 }
1636
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001637 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001638 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001639 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001640 mWallpaperAnimLayerAdjustment = adj;
1641 int curTokenIndex = mWallpaperTokens.size();
1642 while (curTokenIndex > 0) {
1643 curTokenIndex--;
1644 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1645 int curWallpaperIndex = token.windows.size();
1646 while (curWallpaperIndex > 0) {
1647 curWallpaperIndex--;
1648 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1649 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001650 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001651 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001652 }
1653 }
1654 }
1655
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001656 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1657 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001658 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001659 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001660 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001661 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001662 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1663 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1664 changed = wallpaperWin.mXOffset != offset;
1665 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001666 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001667 + wallpaperWin + " x: " + offset);
1668 wallpaperWin.mXOffset = offset;
1669 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001670 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001671 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001672 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001673 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001674 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001675
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001676 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001677 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001678 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1679 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1680 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001681 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001682 + wallpaperWin + " y: " + offset);
1683 changed = true;
1684 wallpaperWin.mYOffset = offset;
1685 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001686 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001687 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001688 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001689 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001690 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001691
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001692 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001693 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001695 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1696 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001697 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001698 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001699 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001700 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001701 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1702 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001703 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001704 if (mWaitingOnWallpaper != null) {
1705 long start = SystemClock.uptimeMillis();
1706 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1707 < start) {
1708 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001709 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001710 "Waiting for offset complete...");
1711 mWindowMap.wait(WALLPAPER_TIMEOUT);
1712 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001713 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001714 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001715 if ((start+WALLPAPER_TIMEOUT)
1716 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001717 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001718 + wallpaperWin);
1719 mLastWallpaperTimeoutTime = start;
1720 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001721 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001722 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001723 }
1724 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001725 } catch (RemoteException e) {
1726 }
1727 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001728
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001729 return changed;
1730 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001731
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001732 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001733 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001734 if (mWaitingOnWallpaper != null &&
1735 mWaitingOnWallpaper.mClient.asBinder() == window) {
1736 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001737 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001738 }
1739 }
1740 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001741
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001742 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001743 final int dw = mDisplay.getWidth();
1744 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001745
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001746 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001747
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001748 WindowState target = mWallpaperTarget;
1749 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001750 if (target.mWallpaperX >= 0) {
1751 mLastWallpaperX = target.mWallpaperX;
1752 } else if (changingTarget.mWallpaperX >= 0) {
1753 mLastWallpaperX = changingTarget.mWallpaperX;
1754 }
1755 if (target.mWallpaperY >= 0) {
1756 mLastWallpaperY = target.mWallpaperY;
1757 } else if (changingTarget.mWallpaperY >= 0) {
1758 mLastWallpaperY = changingTarget.mWallpaperY;
1759 }
1760 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001761
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001762 int curTokenIndex = mWallpaperTokens.size();
1763 while (curTokenIndex > 0) {
1764 curTokenIndex--;
1765 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1766 int curWallpaperIndex = token.windows.size();
1767 while (curWallpaperIndex > 0) {
1768 curWallpaperIndex--;
1769 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1770 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1771 wallpaper.computeShownFrameLocked();
1772 changed = true;
1773 // We only want to be synchronous with one wallpaper.
1774 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001775 }
1776 }
1777 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001778
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001779 return changed;
1780 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001781
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001782 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001783 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001784 final int dw = mDisplay.getWidth();
1785 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001786
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001787 int curTokenIndex = mWallpaperTokens.size();
1788 while (curTokenIndex > 0) {
1789 curTokenIndex--;
1790 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001791 if (token.hidden == visible) {
1792 token.hidden = !visible;
1793 // Need to do a layout to ensure the wallpaper now has the
1794 // correct size.
1795 mLayoutNeeded = true;
1796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001797
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001798 int curWallpaperIndex = token.windows.size();
1799 while (curWallpaperIndex > 0) {
1800 curWallpaperIndex--;
1801 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1802 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001803 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001804 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001805
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001806 if (wallpaper.mWallpaperVisible != visible) {
1807 wallpaper.mWallpaperVisible = visible;
1808 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001809 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001810 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001811 + ": " + visible);
1812 wallpaper.mClient.dispatchAppVisibility(visible);
1813 } catch (RemoteException e) {
1814 }
1815 }
1816 }
1817 }
1818 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001819
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001820 void sendPointerToWallpaperLocked(WindowState srcWin,
1821 MotionEvent pointer, long eventTime) {
1822 int curTokenIndex = mWallpaperTokens.size();
1823 while (curTokenIndex > 0) {
1824 curTokenIndex--;
1825 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1826 int curWallpaperIndex = token.windows.size();
1827 while (curWallpaperIndex > 0) {
1828 curWallpaperIndex--;
1829 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1830 if ((wallpaper.mAttrs.flags &
1831 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
1832 continue;
1833 }
1834 try {
1835 MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
Dianne Hackborn6adba242009-11-10 11:10:09 -08001836 if (srcWin != null) {
1837 ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
1838 srcWin.mFrame.top-wallpaper.mFrame.top);
1839 } else {
1840 ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
1841 }
1842 switch (pointer.getAction()) {
1843 case MotionEvent.ACTION_DOWN:
1844 mSendingPointersToWallpaper = true;
1845 break;
1846 case MotionEvent.ACTION_UP:
1847 mSendingPointersToWallpaper = false;
1848 break;
1849 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001850 wallpaper.mClient.dispatchPointer(ev, eventTime, false);
1851 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001852 Slog.w(TAG, "Failure sending pointer to wallpaper", e);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001853 }
1854 }
1855 }
1856 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001857
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001858 void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
1859 MotionEvent pointer, long eventTime, boolean skipped) {
1860 if (relWin != null) {
1861 mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
1862 } else {
1863 mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
1864 }
1865
1866 // If we sent an initial down to the wallpaper, then continue
1867 // sending events until the final up.
1868 if (mSendingPointersToWallpaper) {
1869 if (skipped) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 Slog.i(TAG, "Sending skipped pointer to wallpaper!");
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001871 }
1872 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1873
1874 // If we are on top of the wallpaper, then the wallpaper also
1875 // gets to see this movement.
1876 } else if (srcWin != null
1877 && pointer.getAction() == MotionEvent.ACTION_DOWN
1878 && mWallpaperTarget == srcWin
1879 && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
1880 sendPointerToWallpaperLocked(relWin, pointer, eventTime);
1881 }
1882 }
1883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 public int addWindow(Session session, IWindow client,
1885 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001886 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 int res = mPolicy.checkAddPermission(attrs);
1888 if (res != WindowManagerImpl.ADD_OKAY) {
1889 return res;
1890 }
Romain Guy06882f82009-06-10 13:36:04 -07001891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 boolean reportNewConfig = false;
1893 WindowState attachedWindow = null;
1894 WindowState win = null;
Romain Guy06882f82009-06-10 13:36:04 -07001895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 synchronized(mWindowMap) {
1897 // Instantiating a Display requires talking with the simulator,
1898 // so don't do it until we know the system is mostly up and
1899 // running.
1900 if (mDisplay == null) {
1901 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1902 mDisplay = wm.getDefaultDisplay();
Christopher Tateb696aee2010-04-02 19:08:30 -07001903 mInitialDisplayWidth = mDisplay.getWidth();
1904 mInitialDisplayHeight = mDisplay.getHeight();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001905 if (ENABLE_NATIVE_INPUT_DISPATCH) {
1906 mInputManager.setDisplaySize(0,
1907 mInitialDisplayWidth, mInitialDisplayHeight);
1908 } else {
1909 mQueue.setDisplay(mDisplay);
1910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 reportNewConfig = true;
1912 }
Romain Guy06882f82009-06-10 13:36:04 -07001913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001914 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001915 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1917 }
1918
1919 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001920 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001921 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 + attrs.token + ". Aborting.");
1924 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1925 }
1926 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1927 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001928 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 + attrs.token + ". Aborting.");
1930 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1931 }
1932 }
1933
1934 boolean addToken = false;
1935 WindowToken token = mTokenMap.get(attrs.token);
1936 if (token == null) {
1937 if (attrs.type >= FIRST_APPLICATION_WINDOW
1938 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001939 Slog.w(TAG, "Attempted to add application 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 }
1943 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001944 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 + attrs.token + ". Aborting.");
1946 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1947 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001948 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001949 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001950 + attrs.token + ". Aborting.");
1951 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 token = new WindowToken(attrs.token, -1, false);
1954 addToken = true;
1955 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1956 && attrs.type <= LAST_APPLICATION_WINDOW) {
1957 AppWindowToken atoken = token.appWindowToken;
1958 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001959 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 + token + ". Aborting.");
1961 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1962 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001963 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 + token + ". Aborting.");
1965 return WindowManagerImpl.ADD_APP_EXITING;
1966 }
1967 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1968 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001969 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1971 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1972 }
1973 } else if (attrs.type == TYPE_INPUT_METHOD) {
1974 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001975 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976 + attrs.token + ". Aborting.");
1977 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1978 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001979 } else if (attrs.type == TYPE_WALLPAPER) {
1980 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001981 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001982 + attrs.token + ". Aborting.");
1983 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 }
1986
1987 win = new WindowState(session, client, token,
1988 attachedWindow, attrs, viewVisibility);
1989 if (win.mDeathRecipient == null) {
1990 // Client has apparently died, so there is no reason to
1991 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001992 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 + " that is dead, aborting.");
1994 return WindowManagerImpl.ADD_APP_EXITING;
1995 }
1996
1997 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07001998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 res = mPolicy.prepareAddWindowLw(win, attrs);
2000 if (res != WindowManagerImpl.ADD_OKAY) {
2001 return res;
2002 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002003
2004 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2005 if (outInputChannel != null) {
2006 String name = win.makeInputChannelName();
2007 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2008 win.mInputChannel = inputChannels[0];
2009 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2010
2011 mInputManager.registerInputChannel(win.mInputChannel);
2012 }
2013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002014
2015 // From now on, no exceptions or errors allowed!
2016
2017 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002019 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 if (addToken) {
2022 mTokenMap.put(attrs.token, token);
2023 mTokenList.add(token);
2024 }
2025 win.attach();
2026 mWindowMap.put(client.asBinder(), win);
2027
2028 if (attrs.type == TYPE_APPLICATION_STARTING &&
2029 token.appWindowToken != null) {
2030 token.appWindowToken.startingWindow = win;
2031 }
2032
2033 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035 if (attrs.type == TYPE_INPUT_METHOD) {
2036 mInputMethodWindow = win;
2037 addInputMethodWindowToListLocked(win);
2038 imMayMove = false;
2039 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2040 mInputMethodDialogs.add(win);
2041 addWindowToListInOrderLocked(win, true);
2042 adjustInputMethodDialogsLocked();
2043 imMayMove = false;
2044 } else {
2045 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002046 if (attrs.type == TYPE_WALLPAPER) {
2047 mLastWallpaperTimeoutTime = 0;
2048 adjustWallpaperWindowsLocked();
2049 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002050 adjustWallpaperWindowsLocked();
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 }
Romain Guy06882f82009-06-10 13:36:04 -07002053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002054 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 if (mInTouchMode) {
2059 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2060 }
2061 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2062 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2063 }
Romain Guy06882f82009-06-10 13:36:04 -07002064
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002065 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002066 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002067 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2068 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 imMayMove = false;
2070 }
2071 }
Romain Guy06882f82009-06-10 13:36:04 -07002072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002073 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002074 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 }
Romain Guy06882f82009-06-10 13:36:04 -07002076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 assignLayersLocked();
2078 // Don't do layout here, the window must call
2079 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002081 //dump();
2082
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002083 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002084 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002085 }
Jeff Brown349703e2010-06-22 01:27:15 -07002086
Joe Onorato8a9b2202010-02-26 18:56:32 -08002087 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088 TAG, "New client " + client.asBinder()
2089 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002090
2091 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2092 reportNewConfig = true;
2093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 }
2095
2096 // sendNewConfiguration() checks caller permissions so we must call it with
2097 // privilege. updateOrientationFromAppTokens() clears and resets the caller
2098 // identity anyway, so it's safe to just clear & restore around this whole
2099 // block.
2100 final long origId = Binder.clearCallingIdentity();
2101 if (reportNewConfig) {
2102 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 }
2104 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 return res;
2107 }
Romain Guy06882f82009-06-10 13:36:04 -07002108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 public void removeWindow(Session session, IWindow client) {
2110 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002111 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 if (win == null) {
2113 return;
2114 }
2115 removeWindowLocked(session, win);
2116 }
2117 }
Romain Guy06882f82009-06-10 13:36:04 -07002118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 public void removeWindowLocked(Session session, WindowState win) {
2120
Joe Onorato8a9b2202010-02-26 18:56:32 -08002121 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 TAG, "Remove " + win + " client="
2123 + Integer.toHexString(System.identityHashCode(
2124 win.mClient.asBinder()))
2125 + ", surface=" + win.mSurface);
2126
2127 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002128
Joe Onorato8a9b2202010-02-26 18:56:32 -08002129 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2131 + " mExiting=" + win.mExiting
2132 + " isAnimating=" + win.isAnimating()
2133 + " app-animation="
2134 + (win.mAppToken != null ? win.mAppToken.animation : null)
2135 + " inPendingTransaction="
2136 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2137 + " mDisplayFrozen=" + mDisplayFrozen);
2138 // Visibility of the removed window. Will be used later to update orientation later on.
2139 boolean wasVisible = false;
2140 // First, see if we need to run an animation. If we do, we have
2141 // to hold off on removing the window until the animation is done.
2142 // If the display is frozen, just remove immediately, since the
2143 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002144 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 // If we are not currently running the exit animation, we
2146 // need to see about starting one.
2147 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2150 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2151 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2152 }
2153 // Try starting an animation.
2154 if (applyAnimationLocked(win, transit, false)) {
2155 win.mExiting = true;
2156 }
2157 }
2158 if (win.mExiting || win.isAnimating()) {
2159 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002160 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 win.mExiting = true;
2162 win.mRemoveOnExit = true;
2163 mLayoutNeeded = true;
2164 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2165 performLayoutAndPlaceSurfacesLocked();
2166 if (win.mAppToken != null) {
2167 win.mAppToken.updateReportedVisibilityLocked();
2168 }
2169 //dump();
2170 Binder.restoreCallingIdentity(origId);
2171 return;
2172 }
2173 }
2174
2175 removeWindowInnerLocked(session, win);
2176 // Removing a visible window will effect the computed orientation
2177 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002178 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002179 != mForcedAppOrientation
2180 && updateOrientationFromAppTokensLocked()) {
2181 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 }
2183 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2184 Binder.restoreCallingIdentity(origId);
2185 }
Romain Guy06882f82009-06-10 13:36:04 -07002186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 private void removeWindowInnerLocked(Session session, WindowState win) {
Jeff Brown349703e2010-06-22 01:27:15 -07002188 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2189 mInputMonitor.windowIsBeingRemovedLw(win);
2190 } else {
2191 mKeyWaiter.finishedKey(session, win.mClient, true,
2192 KeyWaiter.RETURN_NOTHING);
2193 mKeyWaiter.releasePendingPointerLocked(win.mSession);
2194 mKeyWaiter.releasePendingTrackballLocked(win.mSession);
2195 }
Romain Guy06882f82009-06-10 13:36:04 -07002196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 if (mInputMethodTarget == win) {
2200 moveInputMethodWindowsIfNeededLocked(false);
2201 }
Romain Guy06882f82009-06-10 13:36:04 -07002202
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002203 if (false) {
2204 RuntimeException e = new RuntimeException("here");
2205 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002206 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002207 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 mPolicy.removeWindowLw(win);
2210 win.removeLocked();
2211
2212 mWindowMap.remove(win.mClient.asBinder());
2213 mWindows.remove(win);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002214 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215
2216 if (mInputMethodWindow == win) {
2217 mInputMethodWindow = null;
2218 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2219 mInputMethodDialogs.remove(win);
2220 }
Romain Guy06882f82009-06-10 13:36:04 -07002221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 final WindowToken token = win.mToken;
2223 final AppWindowToken atoken = win.mAppToken;
2224 token.windows.remove(win);
2225 if (atoken != null) {
2226 atoken.allAppWindows.remove(win);
2227 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002228 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 TAG, "**** Removing window " + win + ": count="
2230 + token.windows.size());
2231 if (token.windows.size() == 0) {
2232 if (!token.explicit) {
2233 mTokenMap.remove(token.token);
2234 mTokenList.remove(token);
2235 } else if (atoken != null) {
2236 atoken.firstWindowDrawn = false;
2237 }
2238 }
2239
2240 if (atoken != null) {
2241 if (atoken.startingWindow == win) {
2242 atoken.startingWindow = null;
2243 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2244 // If this is the last window and we had requested a starting
2245 // transition window, well there is no point now.
2246 atoken.startingData = null;
2247 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2248 // If this is the last window except for a starting transition
2249 // window, we need to get rid of the starting transition.
2250 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002251 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 + ": no more real windows");
2253 }
2254 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2255 mH.sendMessage(m);
2256 }
2257 }
Romain Guy06882f82009-06-10 13:36:04 -07002258
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002259 if (win.mAttrs.type == TYPE_WALLPAPER) {
2260 mLastWallpaperTimeoutTime = 0;
2261 adjustWallpaperWindowsLocked();
2262 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002263 adjustWallpaperWindowsLocked();
2264 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 if (!mInLayout) {
2267 assignLayersLocked();
2268 mLayoutNeeded = true;
2269 performLayoutAndPlaceSurfacesLocked();
2270 if (win.mAppToken != null) {
2271 win.mAppToken.updateReportedVisibilityLocked();
2272 }
2273 }
2274 }
2275
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002276 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2277 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2278 + ": " + msg + " / " + w.mAttrs.getTitle();
2279 if (where != null) {
2280 Slog.i(TAG, str, where);
2281 } else {
2282 Slog.i(TAG, str);
2283 }
2284 }
2285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2287 long origId = Binder.clearCallingIdentity();
2288 try {
2289 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002290 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002292 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 Surface.openTransaction();
2294 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002295 if (SHOW_TRANSACTIONS) logSurface(w,
2296 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 w.mSurface.setTransparentRegionHint(region);
2298 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002299 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 Surface.closeTransaction();
2301 }
2302 }
2303 }
2304 } finally {
2305 Binder.restoreCallingIdentity(origId);
2306 }
2307 }
2308
2309 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002310 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 Rect visibleInsets) {
2312 long origId = Binder.clearCallingIdentity();
2313 try {
2314 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002315 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 if (w != null) {
2317 w.mGivenInsetsPending = false;
2318 w.mGivenContentInsets.set(contentInsets);
2319 w.mGivenVisibleInsets.set(visibleInsets);
2320 w.mTouchableInsets = touchableInsets;
2321 mLayoutNeeded = true;
2322 performLayoutAndPlaceSurfacesLocked();
2323 }
2324 }
2325 } finally {
2326 Binder.restoreCallingIdentity(origId);
2327 }
2328 }
Romain Guy06882f82009-06-10 13:36:04 -07002329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 public void getWindowDisplayFrame(Session session, IWindow client,
2331 Rect outDisplayFrame) {
2332 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002333 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 if (win == null) {
2335 outDisplayFrame.setEmpty();
2336 return;
2337 }
2338 outDisplayFrame.set(win.mDisplayFrame);
2339 }
2340 }
2341
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002342 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2343 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002344 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2345 window.mWallpaperX = x;
2346 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002347 window.mWallpaperXStep = xStep;
2348 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002349 if (updateWallpaperOffsetLocked(window, true)) {
2350 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002351 }
2352 }
2353 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002354
Dianne Hackborn75804932009-10-20 20:15:20 -07002355 void wallpaperCommandComplete(IBinder window, Bundle result) {
2356 synchronized (mWindowMap) {
2357 if (mWaitingOnWallpaper != null &&
2358 mWaitingOnWallpaper.mClient.asBinder() == window) {
2359 mWaitingOnWallpaper = null;
2360 mWindowMap.notifyAll();
2361 }
2362 }
2363 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002364
Dianne Hackborn75804932009-10-20 20:15:20 -07002365 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2366 String action, int x, int y, int z, Bundle extras, boolean sync) {
2367 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2368 || window == mUpperWallpaperTarget) {
2369 boolean doWait = sync;
2370 int curTokenIndex = mWallpaperTokens.size();
2371 while (curTokenIndex > 0) {
2372 curTokenIndex--;
2373 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2374 int curWallpaperIndex = token.windows.size();
2375 while (curWallpaperIndex > 0) {
2376 curWallpaperIndex--;
2377 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2378 try {
2379 wallpaper.mClient.dispatchWallpaperCommand(action,
2380 x, y, z, extras, sync);
2381 // We only want to be synchronous with one wallpaper.
2382 sync = false;
2383 } catch (RemoteException e) {
2384 }
2385 }
2386 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002387
Dianne Hackborn75804932009-10-20 20:15:20 -07002388 if (doWait) {
2389 // XXX Need to wait for result.
2390 }
2391 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002392
Dianne Hackborn75804932009-10-20 20:15:20 -07002393 return null;
2394 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 public int relayoutWindow(Session session, IWindow client,
2397 WindowManager.LayoutParams attrs, int requestedWidth,
2398 int requestedHeight, int viewVisibility, boolean insetsPending,
2399 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002400 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 boolean displayed = false;
2402 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002403 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002407 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 if (win == null) {
2409 return 0;
2410 }
2411 win.mRequestedWidth = requestedWidth;
2412 win.mRequestedHeight = requestedHeight;
2413
2414 if (attrs != null) {
2415 mPolicy.adjustWindowParamsLw(attrs);
2416 }
Romain Guy06882f82009-06-10 13:36:04 -07002417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 int attrChanges = 0;
2419 int flagChanges = 0;
2420 if (attrs != null) {
2421 flagChanges = win.mAttrs.flags ^= attrs.flags;
2422 attrChanges = win.mAttrs.copyFrom(attrs);
2423 }
2424
Joe Onorato8a9b2202010-02-26 18:56:32 -08002425 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426
2427 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2428 win.mAlpha = attrs.alpha;
2429 }
2430
2431 final boolean scaledWindow =
2432 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2433
2434 if (scaledWindow) {
2435 // requested{Width|Height} Surface's physical size
2436 // attrs.{width|height} Size on screen
2437 win.mHScale = (attrs.width != requestedWidth) ?
2438 (attrs.width / (float)requestedWidth) : 1.0f;
2439 win.mVScale = (attrs.height != requestedHeight) ?
2440 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002441 } else {
2442 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 }
2444
2445 boolean imMayMove = (flagChanges&(
2446 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2447 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 boolean focusMayChange = win.mViewVisibility != viewVisibility
2450 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2451 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002452
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002453 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2454 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 win.mRelayoutCalled = true;
2457 final int oldVisibility = win.mViewVisibility;
2458 win.mViewVisibility = viewVisibility;
2459 if (viewVisibility == View.VISIBLE &&
2460 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2461 displayed = !win.isVisibleLw();
2462 if (win.mExiting) {
2463 win.mExiting = false;
2464 win.mAnimation = null;
2465 }
2466 if (win.mDestroying) {
2467 win.mDestroying = false;
2468 mDestroySurface.remove(win);
2469 }
2470 if (oldVisibility == View.GONE) {
2471 win.mEnterAnimationPending = true;
2472 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002473 if (displayed) {
2474 if (win.mSurface != null && !win.mDrawPending
2475 && !win.mCommitDrawPending && !mDisplayFrozen
2476 && mPolicy.isScreenOn()) {
2477 applyEnterAnimationLocked(win);
2478 }
2479 if ((win.mAttrs.flags
2480 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2481 if (DEBUG_VISIBILITY) Slog.v(TAG,
2482 "Relayout window turning screen on: " + win);
2483 win.mTurnOnScreen = true;
2484 }
2485 int diff = 0;
2486 if (win.mConfiguration != mCurConfiguration
2487 && (win.mConfiguration == null
2488 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2489 win.mConfiguration = mCurConfiguration;
2490 if (DEBUG_CONFIGURATION) {
2491 Slog.i(TAG, "Window " + win + " visible with new config: "
2492 + win.mConfiguration + " / 0x"
2493 + Integer.toHexString(diff));
2494 }
2495 outConfig.setTo(mCurConfiguration);
2496 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2499 // To change the format, we need to re-build the surface.
2500 win.destroySurfaceLocked();
2501 displayed = true;
2502 }
2503 try {
2504 Surface surface = win.createSurfaceLocked();
2505 if (surface != null) {
2506 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002507 win.mReportDestroySurface = false;
2508 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002509 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002510 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002512 // For some reason there isn't a surface. Clear the
2513 // caller's object so they see the same state.
2514 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 }
2516 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002517 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002518 + client + " (" + win.mAttrs.getTitle() + ")",
2519 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 Binder.restoreCallingIdentity(origId);
2521 return 0;
2522 }
2523 if (displayed) {
2524 focusMayChange = true;
2525 }
2526 if (win.mAttrs.type == TYPE_INPUT_METHOD
2527 && mInputMethodWindow == null) {
2528 mInputMethodWindow = win;
2529 imMayMove = true;
2530 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002531 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2532 && win.mAppToken != null
2533 && win.mAppToken.startingWindow != null) {
2534 // Special handling of starting window over the base
2535 // window of the app: propagate lock screen flags to it,
2536 // to provide the correct semantics while starting.
2537 final int mask =
2538 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002539 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2540 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002541 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2542 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 } else {
2545 win.mEnterAnimationPending = false;
2546 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002547 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002548 + ": mExiting=" + win.mExiting
2549 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 // If we are not currently running the exit animation, we
2551 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002552 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 // Try starting an animation; if there isn't one, we
2554 // can destroy the surface right away.
2555 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2556 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2557 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2558 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002559 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002561 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002562 win.mExiting = true;
Jeff Brown349703e2010-06-22 01:27:15 -07002563 if (ENABLE_NATIVE_INPUT_DISPATCH) {
2564 mInputMonitor.windowIsBecomingInvisibleLw(win);
2565 } else {
2566 mKeyWaiter.finishedKey(session, client, true,
2567 KeyWaiter.RETURN_NOTHING);
2568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 } else if (win.isAnimating()) {
2570 // Currently in a hide animation... turn this into
2571 // an exit.
2572 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002573 } else if (win == mWallpaperTarget) {
2574 // If the wallpaper is currently behind this
2575 // window, we need to change both of them inside
2576 // of a transaction to avoid artifacts.
2577 win.mExiting = true;
2578 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002579 } else {
2580 if (mInputMethodWindow == win) {
2581 mInputMethodWindow = null;
2582 }
2583 win.destroySurfaceLocked();
2584 }
2585 }
2586 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002587
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002588 if (win.mSurface == null || (win.getAttrs().flags
2589 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2590 || win.mSurfacePendingDestroy) {
2591 // We are being called from a local process, which
2592 // means outSurface holds its current surface. Ensure the
2593 // surface object is cleared, but we don't want it actually
2594 // destroyed at this point.
2595 win.mSurfacePendingDestroy = false;
2596 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002597 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002598 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002599 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002600 "Keeping surface, will report destroy: " + win);
2601 win.mReportDestroySurface = true;
2602 outSurface.copyFrom(win.mSurface);
2603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002604 }
2605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 if (focusMayChange) {
2607 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2608 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 imMayMove = false;
2610 }
2611 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2612 }
Romain Guy06882f82009-06-10 13:36:04 -07002613
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002614 // updateFocusedWindowLocked() already assigned layers so we only need to
2615 // reassign them at this point if the IM window state gets shuffled
2616 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002619 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2620 // Little hack here -- we -should- be able to rely on the
2621 // function to return true if the IME has moved and needs
2622 // its layer recomputed. However, if the IME was hidden
2623 // and isn't actually moved in the list, its layer may be
2624 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 assignLayers = true;
2626 }
2627 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002628 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002629 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002630 assignLayers = true;
2631 }
2632 }
Romain Guy06882f82009-06-10 13:36:04 -07002633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 mLayoutNeeded = true;
2635 win.mGivenInsetsPending = insetsPending;
2636 if (assignLayers) {
2637 assignLayersLocked();
2638 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002639 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002640 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002641 if (displayed && win.mIsWallpaper) {
2642 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002643 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 if (win.mAppToken != null) {
2646 win.mAppToken.updateReportedVisibilityLocked();
2647 }
2648 outFrame.set(win.mFrame);
2649 outContentInsets.set(win.mContentInsets);
2650 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002651 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002653 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 + ", requestedHeight=" + requestedHeight
2655 + ", viewVisibility=" + viewVisibility
2656 + "\nRelayout returning frame=" + outFrame
2657 + ", surface=" + outSurface);
2658
Joe Onorato8a9b2202010-02-26 18:56:32 -08002659 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002660 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2661
2662 inTouchMode = mInTouchMode;
2663 }
2664
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002665 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 sendNewConfiguration();
2667 }
Romain Guy06882f82009-06-10 13:36:04 -07002668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2672 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2673 }
2674
2675 public void finishDrawingWindow(Session session, IWindow client) {
2676 final long origId = Binder.clearCallingIdentity();
2677 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002678 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002680 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2681 adjustWallpaperWindowsLocked();
2682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 mLayoutNeeded = true;
2684 performLayoutAndPlaceSurfacesLocked();
2685 }
2686 }
2687 Binder.restoreCallingIdentity(origId);
2688 }
2689
2690 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002691 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 + (lp != null ? lp.packageName : null)
2693 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2694 if (lp != null && lp.windowAnimations != 0) {
2695 // If this is a system resource, don't try to load it from the
2696 // application resources. It is nice to avoid loading application
2697 // resources if we can.
2698 String packageName = lp.packageName != null ? lp.packageName : "android";
2699 int resId = lp.windowAnimations;
2700 if ((resId&0xFF000000) == 0x01000000) {
2701 packageName = "android";
2702 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002703 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 + packageName);
2705 return AttributeCache.instance().get(packageName, resId,
2706 com.android.internal.R.styleable.WindowAnimation);
2707 }
2708 return null;
2709 }
Romain Guy06882f82009-06-10 13:36:04 -07002710
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002711 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002712 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002713 + packageName + " resId=0x" + Integer.toHexString(resId));
2714 if (packageName != null) {
2715 if ((resId&0xFF000000) == 0x01000000) {
2716 packageName = "android";
2717 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002719 + packageName);
2720 return AttributeCache.instance().get(packageName, resId,
2721 com.android.internal.R.styleable.WindowAnimation);
2722 }
2723 return null;
2724 }
2725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 private void applyEnterAnimationLocked(WindowState win) {
2727 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2728 if (win.mEnterAnimationPending) {
2729 win.mEnterAnimationPending = false;
2730 transit = WindowManagerPolicy.TRANSIT_ENTER;
2731 }
2732
2733 applyAnimationLocked(win, transit, true);
2734 }
2735
2736 private boolean applyAnimationLocked(WindowState win,
2737 int transit, boolean isEntrance) {
2738 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2739 // If we are trying to apply an animation, but already running
2740 // an animation of the same type, then just leave that one alone.
2741 return true;
2742 }
Romain Guy06882f82009-06-10 13:36:04 -07002743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 // Only apply an animation if the display isn't frozen. If it is
2745 // frozen, there is no reason to animate and it can cause strange
2746 // artifacts when we unfreeze the display if some different animation
2747 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002748 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 int anim = mPolicy.selectAnimationLw(win, transit);
2750 int attr = -1;
2751 Animation a = null;
2752 if (anim != 0) {
2753 a = AnimationUtils.loadAnimation(mContext, anim);
2754 } else {
2755 switch (transit) {
2756 case WindowManagerPolicy.TRANSIT_ENTER:
2757 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2758 break;
2759 case WindowManagerPolicy.TRANSIT_EXIT:
2760 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2761 break;
2762 case WindowManagerPolicy.TRANSIT_SHOW:
2763 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2764 break;
2765 case WindowManagerPolicy.TRANSIT_HIDE:
2766 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2767 break;
2768 }
2769 if (attr >= 0) {
2770 a = loadAnimation(win.mAttrs, attr);
2771 }
2772 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002773 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2775 + " mAnimation=" + win.mAnimation
2776 + " isEntrance=" + isEntrance);
2777 if (a != null) {
2778 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002779 RuntimeException e = null;
2780 if (!HIDE_STACK_CRAWLS) {
2781 e = new RuntimeException();
2782 e.fillInStackTrace();
2783 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002784 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 }
2786 win.setAnimation(a);
2787 win.mAnimationIsEntrance = isEntrance;
2788 }
2789 } else {
2790 win.clearAnimation();
2791 }
2792
2793 return win.mAnimation != null;
2794 }
2795
2796 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2797 int anim = 0;
2798 Context context = mContext;
2799 if (animAttr >= 0) {
2800 AttributeCache.Entry ent = getCachedAnimations(lp);
2801 if (ent != null) {
2802 context = ent.context;
2803 anim = ent.array.getResourceId(animAttr, 0);
2804 }
2805 }
2806 if (anim != 0) {
2807 return AnimationUtils.loadAnimation(context, anim);
2808 }
2809 return null;
2810 }
Romain Guy06882f82009-06-10 13:36:04 -07002811
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002812 private Animation loadAnimation(String packageName, int resId) {
2813 int anim = 0;
2814 Context context = mContext;
2815 if (resId >= 0) {
2816 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2817 if (ent != null) {
2818 context = ent.context;
2819 anim = resId;
2820 }
2821 }
2822 if (anim != 0) {
2823 return AnimationUtils.loadAnimation(context, anim);
2824 }
2825 return null;
2826 }
2827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002828 private boolean applyAnimationLocked(AppWindowToken wtoken,
2829 WindowManager.LayoutParams lp, int transit, boolean enter) {
2830 // Only apply an animation if the display isn't frozen. If it is
2831 // frozen, there is no reason to animate and it can cause strange
2832 // artifacts when we unfreeze the display if some different animation
2833 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002834 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002835 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002836 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002837 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002838 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002839 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002840 } else if (mNextAppTransitionPackage != null) {
2841 a = loadAnimation(mNextAppTransitionPackage, enter ?
2842 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002843 } else {
2844 int animAttr = 0;
2845 switch (transit) {
2846 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2847 animAttr = enter
2848 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2849 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2850 break;
2851 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2852 animAttr = enter
2853 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2854 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2855 break;
2856 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2857 animAttr = enter
2858 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2859 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2860 break;
2861 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2862 animAttr = enter
2863 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2864 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2865 break;
2866 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2867 animAttr = enter
2868 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2869 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2870 break;
2871 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2872 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002873 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002874 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2875 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002876 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002877 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002878 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2879 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002880 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002881 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002882 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002883 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2884 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2885 break;
2886 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2887 animAttr = enter
2888 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2889 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2890 break;
2891 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2892 animAttr = enter
2893 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2894 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002895 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002896 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002897 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002898 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002899 + " anim=" + a
2900 + " animAttr=0x" + Integer.toHexString(animAttr)
2901 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 if (a != null) {
2904 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002905 RuntimeException e = null;
2906 if (!HIDE_STACK_CRAWLS) {
2907 e = new RuntimeException();
2908 e.fillInStackTrace();
2909 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002910 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 }
2912 wtoken.setAnimation(a);
2913 }
2914 } else {
2915 wtoken.clearAnimation();
2916 }
2917
2918 return wtoken.animation != null;
2919 }
2920
2921 // -------------------------------------------------------------
2922 // Application Window Tokens
2923 // -------------------------------------------------------------
2924
2925 public void validateAppTokens(List tokens) {
2926 int v = tokens.size()-1;
2927 int m = mAppTokens.size()-1;
2928 while (v >= 0 && m >= 0) {
2929 AppWindowToken wtoken = mAppTokens.get(m);
2930 if (wtoken.removed) {
2931 m--;
2932 continue;
2933 }
2934 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002935 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2937 }
2938 v--;
2939 m--;
2940 }
2941 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002942 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 v--;
2944 }
2945 while (m >= 0) {
2946 AppWindowToken wtoken = mAppTokens.get(m);
2947 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002948 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 }
2950 m--;
2951 }
2952 }
2953
2954 boolean checkCallingPermission(String permission, String func) {
2955 // Quick check: if the calling permission is me, it's all okay.
2956 if (Binder.getCallingPid() == Process.myPid()) {
2957 return true;
2958 }
Romain Guy06882f82009-06-10 13:36:04 -07002959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 if (mContext.checkCallingPermission(permission)
2961 == PackageManager.PERMISSION_GRANTED) {
2962 return true;
2963 }
2964 String msg = "Permission Denial: " + func + " from pid="
2965 + Binder.getCallingPid()
2966 + ", uid=" + Binder.getCallingUid()
2967 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002968 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002969 return false;
2970 }
Romain Guy06882f82009-06-10 13:36:04 -07002971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 AppWindowToken findAppWindowToken(IBinder token) {
2973 WindowToken wtoken = mTokenMap.get(token);
2974 if (wtoken == null) {
2975 return null;
2976 }
2977 return wtoken.appWindowToken;
2978 }
Romain Guy06882f82009-06-10 13:36:04 -07002979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 public void addWindowToken(IBinder token, int type) {
2981 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2982 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07002983 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 }
Romain Guy06882f82009-06-10 13:36:04 -07002985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 synchronized(mWindowMap) {
2987 WindowToken wtoken = mTokenMap.get(token);
2988 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002989 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 return;
2991 }
2992 wtoken = new WindowToken(token, type, true);
2993 mTokenMap.put(token, wtoken);
2994 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002995 if (type == TYPE_WALLPAPER) {
2996 mWallpaperTokens.add(wtoken);
2997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 }
2999 }
Romain Guy06882f82009-06-10 13:36:04 -07003000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 public void removeWindowToken(IBinder token) {
3002 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3003 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003004 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 }
3006
3007 final long origId = Binder.clearCallingIdentity();
3008 synchronized(mWindowMap) {
3009 WindowToken wtoken = mTokenMap.remove(token);
3010 mTokenList.remove(wtoken);
3011 if (wtoken != null) {
3012 boolean delayed = false;
3013 if (!wtoken.hidden) {
3014 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 final int N = wtoken.windows.size();
3017 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 for (int i=0; i<N; i++) {
3020 WindowState win = wtoken.windows.get(i);
3021
3022 if (win.isAnimating()) {
3023 delayed = true;
3024 }
Romain Guy06882f82009-06-10 13:36:04 -07003025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 if (win.isVisibleNow()) {
3027 applyAnimationLocked(win,
3028 WindowManagerPolicy.TRANSIT_EXIT, false);
Jeff Brown349703e2010-06-22 01:27:15 -07003029 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3030 mInputMonitor.windowIsBeingRemovedLw(win);
3031 } else {
3032 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3033 KeyWaiter.RETURN_NOTHING);
3034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 changed = true;
3036 }
3037 }
3038
3039 if (changed) {
3040 mLayoutNeeded = true;
3041 performLayoutAndPlaceSurfacesLocked();
3042 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3043 }
Romain Guy06882f82009-06-10 13:36:04 -07003044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003045 if (delayed) {
3046 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003047 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3048 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 }
3050 }
Romain Guy06882f82009-06-10 13:36:04 -07003051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003052 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003053 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 }
3055 }
3056 Binder.restoreCallingIdentity(origId);
3057 }
3058
3059 public void addAppToken(int addPos, IApplicationToken token,
3060 int groupId, int requestedOrientation, boolean fullscreen) {
3061 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3062 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003063 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 }
Jeff Brown349703e2010-06-22 01:27:15 -07003065
3066 // Get the dispatching timeout here while we are not holding any locks so that it
3067 // can be cached by the AppWindowToken. The timeout value is used later by the
3068 // input dispatcher in code that does hold locks. If we did not cache the value
3069 // here we would run the chance of introducing a deadlock between the window manager
3070 // (which holds locks while updating the input dispatcher state) and the activity manager
3071 // (which holds locks while querying the application token).
3072 long inputDispatchingTimeoutNanos;
3073 try {
3074 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3075 } catch (RemoteException ex) {
3076 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3077 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3078 }
Romain Guy06882f82009-06-10 13:36:04 -07003079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 synchronized(mWindowMap) {
3081 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3082 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003083 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 return;
3085 }
3086 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003087 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 wtoken.groupId = groupId;
3089 wtoken.appFullscreen = fullscreen;
3090 wtoken.requestedOrientation = requestedOrientation;
3091 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003092 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 mTokenMap.put(token.asBinder(), wtoken);
3094 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003096 // Application tokens start out hidden.
3097 wtoken.hidden = true;
3098 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003100 //dump();
3101 }
3102 }
Romain Guy06882f82009-06-10 13:36:04 -07003103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 public void setAppGroupId(IBinder token, int groupId) {
3105 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3106 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003107 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003108 }
3109
3110 synchronized(mWindowMap) {
3111 AppWindowToken wtoken = findAppWindowToken(token);
3112 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003113 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003114 return;
3115 }
3116 wtoken.groupId = groupId;
3117 }
3118 }
Romain Guy06882f82009-06-10 13:36:04 -07003119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 public int getOrientationFromWindowsLocked() {
3121 int pos = mWindows.size() - 1;
3122 while (pos >= 0) {
3123 WindowState wtoken = (WindowState) mWindows.get(pos);
3124 pos--;
3125 if (wtoken.mAppToken != null) {
3126 // We hit an application window. so the orientation will be determined by the
3127 // app window. No point in continuing further.
3128 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3129 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003130 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003131 continue;
3132 }
3133 int req = wtoken.mAttrs.screenOrientation;
3134 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3135 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3136 continue;
3137 } else {
3138 return req;
3139 }
3140 }
3141 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3142 }
Romain Guy06882f82009-06-10 13:36:04 -07003143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003145 int pos = mAppTokens.size() - 1;
3146 int curGroup = 0;
3147 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3148 boolean findingBehind = false;
3149 boolean haveGroup = false;
3150 boolean lastFullscreen = false;
3151 while (pos >= 0) {
3152 AppWindowToken wtoken = mAppTokens.get(pos);
3153 pos--;
3154 // if we're about to tear down this window and not seek for
3155 // the behind activity, don't use it for orientation
3156 if (!findingBehind
3157 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3158 continue;
3159 }
3160
3161 if (!haveGroup) {
3162 // We ignore any hidden applications on the top.
3163 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003164 continue;
3165 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003166 haveGroup = true;
3167 curGroup = wtoken.groupId;
3168 lastOrientation = wtoken.requestedOrientation;
3169 } else if (curGroup != wtoken.groupId) {
3170 // If we have hit a new application group, and the bottom
3171 // of the previous group didn't explicitly say to use
3172 // the orientation behind it, and the last app was
3173 // full screen, then we'll stick with the
3174 // user's orientation.
3175 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3176 && lastFullscreen) {
3177 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003180 int or = wtoken.requestedOrientation;
3181 // If this application is fullscreen, and didn't explicitly say
3182 // to use the orientation behind it, then just take whatever
3183 // orientation it has and ignores whatever is under it.
3184 lastFullscreen = wtoken.appFullscreen;
3185 if (lastFullscreen
3186 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3187 return or;
3188 }
3189 // If this application has requested an explicit orientation,
3190 // then use it.
3191 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3192 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3193 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3194 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3195 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3196 return or;
3197 }
3198 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3199 }
3200 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003201 }
Romain Guy06882f82009-06-10 13:36:04 -07003202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003203 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003204 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003205 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3206 "updateOrientationFromAppTokens()")) {
3207 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3208 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003209
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003210 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003211 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003212
3213 synchronized(mWindowMap) {
3214 if (updateOrientationFromAppTokensLocked()) {
3215 if (freezeThisOneIfNeeded != null) {
3216 AppWindowToken wtoken = findAppWindowToken(
3217 freezeThisOneIfNeeded);
3218 if (wtoken != null) {
3219 startAppFreezingScreenLocked(wtoken,
3220 ActivityInfo.CONFIG_ORIENTATION);
3221 }
3222 }
3223 config = computeNewConfigurationLocked();
3224
3225 } else if (currentConfig != null) {
3226 // No obvious action we need to take, but if our current
3227 // state mismatches the activity maanager's, update it
3228 mTempConfiguration.setToDefaults();
3229 if (computeNewConfigurationLocked(mTempConfiguration)) {
3230 if (currentConfig.diff(mTempConfiguration) != 0) {
3231 mWaitingForConfig = true;
3232 mLayoutNeeded = true;
3233 startFreezingDisplayLocked();
3234 config = new Configuration(mTempConfiguration);
3235 }
3236 }
3237 }
3238 }
3239
Dianne Hackborncfaef692009-06-15 14:24:44 -07003240 Binder.restoreCallingIdentity(ident);
3241 return config;
3242 }
3243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003244 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003245 * Determine the new desired orientation of the display, returning
3246 * a non-null new Configuration if it has changed from the current
3247 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3248 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3249 * SCREEN. This will typically be done for you if you call
3250 * sendNewConfiguration().
3251 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003252 * The orientation is computed from non-application windows first. If none of
3253 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003254 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3256 * android.os.IBinder)
3257 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003258 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003259 if (mDisplayFrozen) {
3260 // If the display is frozen, some activities may be in the middle
3261 // of restarting, and thus have removed their old window. If the
3262 // window has the flag to hide the lock screen, then the lock screen
3263 // can re-appear and inflict its own orientation on us. Keep the
3264 // orientation stable until this all settles down.
3265 return false;
3266 }
3267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003269 long ident = Binder.clearCallingIdentity();
3270 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003271 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003274 mForcedAppOrientation = req;
3275 //send a message to Policy indicating orientation change to take
3276 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003277 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003278 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3279 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3280 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003281 }
3282 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003283
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003284 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 } finally {
3286 Binder.restoreCallingIdentity(ident);
3287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288 }
Romain Guy06882f82009-06-10 13:36:04 -07003289
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003290 int computeForcedAppOrientationLocked() {
3291 int req = getOrientationFromWindowsLocked();
3292 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3293 req = getOrientationFromAppTokensLocked();
3294 }
3295 return req;
3296 }
Romain Guy06882f82009-06-10 13:36:04 -07003297
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003298 public void setNewConfiguration(Configuration config) {
3299 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3300 "setNewConfiguration()")) {
3301 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3302 }
3303
3304 synchronized(mWindowMap) {
3305 mCurConfiguration = new Configuration(config);
3306 mWaitingForConfig = false;
3307 performLayoutAndPlaceSurfacesLocked();
3308 }
3309 }
3310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3312 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3313 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003314 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 }
Romain Guy06882f82009-06-10 13:36:04 -07003316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 synchronized(mWindowMap) {
3318 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3319 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003320 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 return;
3322 }
Romain Guy06882f82009-06-10 13:36:04 -07003323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 wtoken.requestedOrientation = requestedOrientation;
3325 }
3326 }
Romain Guy06882f82009-06-10 13:36:04 -07003327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 public int getAppOrientation(IApplicationToken token) {
3329 synchronized(mWindowMap) {
3330 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3331 if (wtoken == null) {
3332 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3333 }
Romain Guy06882f82009-06-10 13:36:04 -07003334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 return wtoken.requestedOrientation;
3336 }
3337 }
Romain Guy06882f82009-06-10 13:36:04 -07003338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3340 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3341 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003342 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 }
3344
3345 synchronized(mWindowMap) {
3346 boolean changed = false;
3347 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003348 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 changed = mFocusedApp != null;
3350 mFocusedApp = null;
Jeff Brown349703e2010-06-22 01:27:15 -07003351 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3352 if (changed) {
3353 mInputMonitor.setFocusedAppLw(null);
3354 }
3355 } else {
3356 mKeyWaiter.tickle();
3357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 } else {
3359 AppWindowToken newFocus = findAppWindowToken(token);
3360 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003361 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 return;
3363 }
3364 changed = mFocusedApp != newFocus;
3365 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003366 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown349703e2010-06-22 01:27:15 -07003367 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3368 if (changed) {
3369 mInputMonitor.setFocusedAppLw(newFocus);
3370 }
3371 } else {
3372 mKeyWaiter.tickle();
3373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003374 }
3375
3376 if (moveFocusNow && changed) {
3377 final long origId = Binder.clearCallingIdentity();
3378 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3379 Binder.restoreCallingIdentity(origId);
3380 }
3381 }
3382 }
3383
3384 public void prepareAppTransition(int transit) {
3385 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3386 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003387 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 }
Romain Guy06882f82009-06-10 13:36:04 -07003389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003391 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 TAG, "Prepare app transition: transit=" + transit
3393 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003394 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003395 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3396 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003398 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3399 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3400 // Opening a new task always supersedes a close for the anim.
3401 mNextAppTransition = transit;
3402 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3403 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3404 // Opening a new activity always supersedes a close for the anim.
3405 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 }
3407 mAppTransitionReady = false;
3408 mAppTransitionTimeout = false;
3409 mStartingIconInTransition = false;
3410 mSkipAppTransitionAnimation = false;
3411 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3412 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3413 5000);
3414 }
3415 }
3416 }
3417
3418 public int getPendingAppTransition() {
3419 return mNextAppTransition;
3420 }
Romain Guy06882f82009-06-10 13:36:04 -07003421
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003422 public void overridePendingAppTransition(String packageName,
3423 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003424 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003425 mNextAppTransitionPackage = packageName;
3426 mNextAppTransitionEnter = enterAnim;
3427 mNextAppTransitionExit = exitAnim;
3428 }
3429 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003431 public void executeAppTransition() {
3432 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3433 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003434 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 }
Romain Guy06882f82009-06-10 13:36:04 -07003436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003438 if (DEBUG_APP_TRANSITIONS) {
3439 RuntimeException e = new RuntimeException("here");
3440 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003441 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003442 + mNextAppTransition, e);
3443 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003444 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 mAppTransitionReady = true;
3446 final long origId = Binder.clearCallingIdentity();
3447 performLayoutAndPlaceSurfacesLocked();
3448 Binder.restoreCallingIdentity(origId);
3449 }
3450 }
3451 }
3452
3453 public void setAppStartingWindow(IBinder token, String pkg,
3454 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3455 IBinder transferFrom, boolean createIfNeeded) {
3456 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3457 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003458 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 }
3460
3461 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003462 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3464 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 AppWindowToken wtoken = findAppWindowToken(token);
3467 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003468 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 return;
3470 }
3471
3472 // If the display is frozen, we won't do anything until the
3473 // actual window is displayed so there is no reason to put in
3474 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003475 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 return;
3477 }
Romain Guy06882f82009-06-10 13:36:04 -07003478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 if (wtoken.startingData != null) {
3480 return;
3481 }
Romain Guy06882f82009-06-10 13:36:04 -07003482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 if (transferFrom != null) {
3484 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3485 if (ttoken != null) {
3486 WindowState startingWindow = ttoken.startingWindow;
3487 if (startingWindow != null) {
3488 if (mStartingIconInTransition) {
3489 // In this case, the starting icon has already
3490 // been displayed, so start letting windows get
3491 // shown immediately without any more transitions.
3492 mSkipAppTransitionAnimation = true;
3493 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003494 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 "Moving existing starting from " + ttoken
3496 + " to " + wtoken);
3497 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003499 // Transfer the starting window over to the new
3500 // token.
3501 wtoken.startingData = ttoken.startingData;
3502 wtoken.startingView = ttoken.startingView;
3503 wtoken.startingWindow = startingWindow;
3504 ttoken.startingData = null;
3505 ttoken.startingView = null;
3506 ttoken.startingWindow = null;
3507 ttoken.startingMoved = true;
3508 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003509 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003511 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003512 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 mWindows.remove(startingWindow);
3514 ttoken.windows.remove(startingWindow);
3515 ttoken.allAppWindows.remove(startingWindow);
3516 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 // Propagate other interesting state between the
3519 // tokens. If the old token is displayed, we should
3520 // immediately force the new one to be displayed. If
3521 // it is animating, we need to move that animation to
3522 // the new one.
3523 if (ttoken.allDrawn) {
3524 wtoken.allDrawn = true;
3525 }
3526 if (ttoken.firstWindowDrawn) {
3527 wtoken.firstWindowDrawn = true;
3528 }
3529 if (!ttoken.hidden) {
3530 wtoken.hidden = false;
3531 wtoken.hiddenRequested = false;
3532 wtoken.willBeHidden = false;
3533 }
3534 if (wtoken.clientHidden != ttoken.clientHidden) {
3535 wtoken.clientHidden = ttoken.clientHidden;
3536 wtoken.sendAppVisibilityToClients();
3537 }
3538 if (ttoken.animation != null) {
3539 wtoken.animation = ttoken.animation;
3540 wtoken.animating = ttoken.animating;
3541 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3542 ttoken.animation = null;
3543 ttoken.animLayerAdjustment = 0;
3544 wtoken.updateLayers();
3545 ttoken.updateLayers();
3546 }
Romain Guy06882f82009-06-10 13:36:04 -07003547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 mLayoutNeeded = true;
3550 performLayoutAndPlaceSurfacesLocked();
3551 Binder.restoreCallingIdentity(origId);
3552 return;
3553 } else if (ttoken.startingData != null) {
3554 // The previous app was getting ready to show a
3555 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003556 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 "Moving pending starting from " + ttoken
3558 + " to " + wtoken);
3559 wtoken.startingData = ttoken.startingData;
3560 ttoken.startingData = null;
3561 ttoken.startingMoved = true;
3562 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3563 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3564 // want to process the message ASAP, before any other queued
3565 // messages.
3566 mH.sendMessageAtFrontOfQueue(m);
3567 return;
3568 }
3569 }
3570 }
3571
3572 // There is no existing starting window, and the caller doesn't
3573 // want us to create one, so that's it!
3574 if (!createIfNeeded) {
3575 return;
3576 }
Romain Guy06882f82009-06-10 13:36:04 -07003577
Dianne Hackborn284ac932009-08-28 10:34:25 -07003578 // If this is a translucent or wallpaper window, then don't
3579 // show a starting window -- the current effect (a full-screen
3580 // opaque starting window that fades away to the real contents
3581 // when it is ready) does not work for this.
3582 if (theme != 0) {
3583 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3584 com.android.internal.R.styleable.Window);
3585 if (ent.array.getBoolean(
3586 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3587 return;
3588 }
3589 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003590 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3591 return;
3592 }
3593 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003594 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3595 return;
3596 }
3597 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 mStartingIconInTransition = true;
3600 wtoken.startingData = new StartingData(
3601 pkg, theme, nonLocalizedLabel,
3602 labelRes, icon);
3603 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3604 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3605 // want to process the message ASAP, before any other queued
3606 // messages.
3607 mH.sendMessageAtFrontOfQueue(m);
3608 }
3609 }
3610
3611 public void setAppWillBeHidden(IBinder token) {
3612 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3613 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003614 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 }
3616
3617 AppWindowToken wtoken;
3618
3619 synchronized(mWindowMap) {
3620 wtoken = findAppWindowToken(token);
3621 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003622 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 -08003623 return;
3624 }
3625 wtoken.willBeHidden = true;
3626 }
3627 }
Romain Guy06882f82009-06-10 13:36:04 -07003628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3630 boolean visible, int transit, boolean performLayout) {
3631 boolean delayed = false;
3632
3633 if (wtoken.clientHidden == visible) {
3634 wtoken.clientHidden = !visible;
3635 wtoken.sendAppVisibilityToClients();
3636 }
Romain Guy06882f82009-06-10 13:36:04 -07003637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 wtoken.willBeHidden = false;
3639 if (wtoken.hidden == visible) {
3640 final int N = wtoken.allAppWindows.size();
3641 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003642 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3644 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003647
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003648 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 if (wtoken.animation == sDummyAnimation) {
3650 wtoken.animation = null;
3651 }
3652 applyAnimationLocked(wtoken, lp, transit, visible);
3653 changed = true;
3654 if (wtoken.animation != null) {
3655 delayed = runningAppAnimation = true;
3656 }
3657 }
Romain Guy06882f82009-06-10 13:36:04 -07003658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 for (int i=0; i<N; i++) {
3660 WindowState win = wtoken.allAppWindows.get(i);
3661 if (win == wtoken.startingWindow) {
3662 continue;
3663 }
3664
3665 if (win.isAnimating()) {
3666 delayed = true;
3667 }
Romain Guy06882f82009-06-10 13:36:04 -07003668
Joe Onorato8a9b2202010-02-26 18:56:32 -08003669 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 //win.dump(" ");
3671 if (visible) {
3672 if (!win.isVisibleNow()) {
3673 if (!runningAppAnimation) {
3674 applyAnimationLocked(win,
3675 WindowManagerPolicy.TRANSIT_ENTER, true);
3676 }
3677 changed = true;
3678 }
3679 } else if (win.isVisibleNow()) {
3680 if (!runningAppAnimation) {
3681 applyAnimationLocked(win,
3682 WindowManagerPolicy.TRANSIT_EXIT, false);
3683 }
Jeff Brown349703e2010-06-22 01:27:15 -07003684 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3685 mInputMonitor.windowIsBecomingInvisibleLw(win);
3686 } else {
3687 mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
3688 KeyWaiter.RETURN_NOTHING);
3689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 changed = true;
3691 }
3692 }
3693
3694 wtoken.hidden = wtoken.hiddenRequested = !visible;
3695 if (!visible) {
3696 unsetAppFreezingScreenLocked(wtoken, true, true);
3697 } else {
3698 // If we are being set visible, and the starting window is
3699 // not yet displayed, then make sure it doesn't get displayed.
3700 WindowState swin = wtoken.startingWindow;
3701 if (swin != null && (swin.mDrawPending
3702 || swin.mCommitDrawPending)) {
3703 swin.mPolicyVisibility = false;
3704 swin.mPolicyVisibilityAfterAnim = false;
3705 }
3706 }
Romain Guy06882f82009-06-10 13:36:04 -07003707
Joe Onorato8a9b2202010-02-26 18:56:32 -08003708 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3710 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003711
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003712 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003714 if (performLayout) {
3715 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3716 performLayoutAndPlaceSurfacesLocked();
3717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 }
3719 }
3720
3721 if (wtoken.animation != null) {
3722 delayed = true;
3723 }
Romain Guy06882f82009-06-10 13:36:04 -07003724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 return delayed;
3726 }
3727
3728 public void setAppVisibility(IBinder token, boolean visible) {
3729 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3730 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003731 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 }
3733
3734 AppWindowToken wtoken;
3735
3736 synchronized(mWindowMap) {
3737 wtoken = findAppWindowToken(token);
3738 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003739 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740 return;
3741 }
3742
3743 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003744 RuntimeException e = null;
3745 if (!HIDE_STACK_CRAWLS) {
3746 e = new RuntimeException();
3747 e.fillInStackTrace();
3748 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003749 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 + "): mNextAppTransition=" + mNextAppTransition
3751 + " hidden=" + wtoken.hidden
3752 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3753 }
Romain Guy06882f82009-06-10 13:36:04 -07003754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 // If we are preparing an app transition, then delay changing
3756 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003757 if (!mDisplayFrozen && mPolicy.isScreenOn()
3758 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003759 // Already in requested state, don't do anything more.
3760 if (wtoken.hiddenRequested != visible) {
3761 return;
3762 }
3763 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003764
Joe Onorato8a9b2202010-02-26 18:56:32 -08003765 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 TAG, "Setting dummy animation on: " + wtoken);
3767 wtoken.setDummyAnimation();
3768 mOpeningApps.remove(wtoken);
3769 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003770 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 wtoken.inPendingTransaction = true;
3772 if (visible) {
3773 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 wtoken.startingDisplayed = false;
3775 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003776
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003777 // If the token is currently hidden (should be the
3778 // common case), then we need to set up to wait for
3779 // its windows to be ready.
3780 if (wtoken.hidden) {
3781 wtoken.allDrawn = false;
3782 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003783
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003784 if (wtoken.clientHidden) {
3785 // In the case where we are making an app visible
3786 // but holding off for a transition, we still need
3787 // to tell the client to make its windows visible so
3788 // they get drawn. Otherwise, we will wait on
3789 // performing the transition until all windows have
3790 // been drawn, they never will be, and we are sad.
3791 wtoken.clientHidden = false;
3792 wtoken.sendAppVisibilityToClients();
3793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
3795 } else {
3796 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003797
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003798 // If the token is currently visible (should be the
3799 // common case), then set up to wait for it to be hidden.
3800 if (!wtoken.hidden) {
3801 wtoken.waitingToHide = true;
3802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 }
3804 return;
3805 }
Romain Guy06882f82009-06-10 13:36:04 -07003806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003808 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003809 wtoken.updateReportedVisibilityLocked();
3810 Binder.restoreCallingIdentity(origId);
3811 }
3812 }
3813
3814 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3815 boolean unfreezeSurfaceNow, boolean force) {
3816 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003817 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 + " force=" + force);
3819 final int N = wtoken.allAppWindows.size();
3820 boolean unfrozeWindows = false;
3821 for (int i=0; i<N; i++) {
3822 WindowState w = wtoken.allAppWindows.get(i);
3823 if (w.mAppFreezing) {
3824 w.mAppFreezing = false;
3825 if (w.mSurface != null && !w.mOrientationChanging) {
3826 w.mOrientationChanging = true;
3827 }
3828 unfrozeWindows = true;
3829 }
3830 }
3831 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003832 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 wtoken.freezingScreen = false;
3834 mAppsFreezingScreen--;
3835 }
3836 if (unfreezeSurfaceNow) {
3837 if (unfrozeWindows) {
3838 mLayoutNeeded = true;
3839 performLayoutAndPlaceSurfacesLocked();
3840 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003841 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 }
3843 }
3844 }
Romain Guy06882f82009-06-10 13:36:04 -07003845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3847 int configChanges) {
3848 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003849 RuntimeException e = null;
3850 if (!HIDE_STACK_CRAWLS) {
3851 e = new RuntimeException();
3852 e.fillInStackTrace();
3853 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003854 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 + ": hidden=" + wtoken.hidden + " freezing="
3856 + wtoken.freezingScreen, e);
3857 }
3858 if (!wtoken.hiddenRequested) {
3859 if (!wtoken.freezingScreen) {
3860 wtoken.freezingScreen = true;
3861 mAppsFreezingScreen++;
3862 if (mAppsFreezingScreen == 1) {
3863 startFreezingDisplayLocked();
3864 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3865 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3866 5000);
3867 }
3868 }
3869 final int N = wtoken.allAppWindows.size();
3870 for (int i=0; i<N; i++) {
3871 WindowState w = wtoken.allAppWindows.get(i);
3872 w.mAppFreezing = true;
3873 }
3874 }
3875 }
Romain Guy06882f82009-06-10 13:36:04 -07003876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 public void startAppFreezingScreen(IBinder token, int configChanges) {
3878 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3879 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003880 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003881 }
3882
3883 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003884 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003885 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 return;
3887 }
Romain Guy06882f82009-06-10 13:36:04 -07003888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 AppWindowToken wtoken = findAppWindowToken(token);
3890 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003891 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 return;
3893 }
3894 final long origId = Binder.clearCallingIdentity();
3895 startAppFreezingScreenLocked(wtoken, configChanges);
3896 Binder.restoreCallingIdentity(origId);
3897 }
3898 }
Romain Guy06882f82009-06-10 13:36:04 -07003899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 public void stopAppFreezingScreen(IBinder token, boolean force) {
3901 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3902 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003903 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
3905
3906 synchronized(mWindowMap) {
3907 AppWindowToken wtoken = findAppWindowToken(token);
3908 if (wtoken == null || wtoken.appToken == null) {
3909 return;
3910 }
3911 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003912 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3914 unsetAppFreezingScreenLocked(wtoken, true, force);
3915 Binder.restoreCallingIdentity(origId);
3916 }
3917 }
Romain Guy06882f82009-06-10 13:36:04 -07003918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 public void removeAppToken(IBinder token) {
3920 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3921 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003922 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 }
3924
3925 AppWindowToken wtoken = null;
3926 AppWindowToken startingToken = null;
3927 boolean delayed = false;
3928
3929 final long origId = Binder.clearCallingIdentity();
3930 synchronized(mWindowMap) {
3931 WindowToken basewtoken = mTokenMap.remove(token);
3932 mTokenList.remove(basewtoken);
3933 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003935 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 wtoken.inPendingTransaction = false;
3937 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003938 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 if (mClosingApps.contains(wtoken)) {
3940 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003941 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003943 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 delayed = true;
3945 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003946 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 TAG, "Removing app " + wtoken + " delayed=" + delayed
3948 + " animation=" + wtoken.animation
3949 + " animating=" + wtoken.animating);
3950 if (delayed) {
3951 // set the token aside because it has an active animation to be finished
3952 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003953 } else {
3954 // Make sure there is no animation running on this token,
3955 // so any windows associated with it will be removed as
3956 // soon as their animations are complete
3957 wtoken.animation = null;
3958 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 }
3960 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003961 if (mLastEnterAnimToken == wtoken) {
3962 mLastEnterAnimToken = null;
3963 mLastEnterAnimParams = null;
3964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 wtoken.removed = true;
3966 if (wtoken.startingData != null) {
3967 startingToken = wtoken;
3968 }
3969 unsetAppFreezingScreenLocked(wtoken, true, true);
3970 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003971 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 mFocusedApp = null;
3973 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown349703e2010-06-22 01:27:15 -07003974 if (ENABLE_NATIVE_INPUT_DISPATCH) {
3975 mInputMonitor.setFocusedAppLw(null);
3976 } else {
3977 mKeyWaiter.tickle();
3978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 }
3980 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003981 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 }
Romain Guy06882f82009-06-10 13:36:04 -07003983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 if (!delayed && wtoken != null) {
3985 wtoken.updateReportedVisibilityLocked();
3986 }
3987 }
3988 Binder.restoreCallingIdentity(origId);
3989
3990 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003991 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 + startingToken + ": app token removed");
3993 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
3994 mH.sendMessage(m);
3995 }
3996 }
3997
3998 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
3999 final int NW = token.windows.size();
4000 for (int i=0; i<NW; i++) {
4001 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004002 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 mWindows.remove(win);
4004 int j = win.mChildWindows.size();
4005 while (j > 0) {
4006 j--;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004007 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004008 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004009 "Tmp removing child window " + cwin);
4010 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 }
4012 }
4013 return NW > 0;
4014 }
4015
4016 void dumpAppTokensLocked() {
4017 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004018 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 }
4020 }
Romain Guy06882f82009-06-10 13:36:04 -07004021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 void dumpWindowsLocked() {
4023 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004024 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 }
4026 }
Romain Guy06882f82009-06-10 13:36:04 -07004027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 private int findWindowOffsetLocked(int tokenPos) {
4029 final int NW = mWindows.size();
4030
4031 if (tokenPos >= mAppTokens.size()) {
4032 int i = NW;
4033 while (i > 0) {
4034 i--;
4035 WindowState win = (WindowState)mWindows.get(i);
4036 if (win.getAppToken() != null) {
4037 return i+1;
4038 }
4039 }
4040 }
4041
4042 while (tokenPos > 0) {
4043 // Find the first app token below the new position that has
4044 // a window displayed.
4045 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004046 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004048 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004049 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004050 "Skipping token -- currently sending to bottom");
4051 tokenPos--;
4052 continue;
4053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 int i = wtoken.windows.size();
4055 while (i > 0) {
4056 i--;
4057 WindowState win = wtoken.windows.get(i);
4058 int j = win.mChildWindows.size();
4059 while (j > 0) {
4060 j--;
4061 WindowState cwin = (WindowState)win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004062 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 for (int pos=NW-1; pos>=0; pos--) {
4064 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004065 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 "Found child win @" + (pos+1));
4067 return pos+1;
4068 }
4069 }
4070 }
4071 }
4072 for (int pos=NW-1; pos>=0; pos--) {
4073 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004074 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 return pos+1;
4076 }
4077 }
4078 }
4079 tokenPos--;
4080 }
4081
4082 return 0;
4083 }
4084
4085 private final int reAddWindowLocked(int index, WindowState win) {
4086 final int NCW = win.mChildWindows.size();
4087 boolean added = false;
4088 for (int j=0; j<NCW; j++) {
4089 WindowState cwin = (WindowState)win.mChildWindows.get(j);
4090 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004091 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004092 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 mWindows.add(index, win);
4094 index++;
4095 added = true;
4096 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004097 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004098 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 mWindows.add(index, cwin);
4100 index++;
4101 }
4102 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004103 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004104 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 mWindows.add(index, win);
4106 index++;
4107 }
4108 return index;
4109 }
Romain Guy06882f82009-06-10 13:36:04 -07004110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4112 final int NW = token.windows.size();
4113 for (int i=0; i<NW; i++) {
4114 index = reAddWindowLocked(index, token.windows.get(i));
4115 }
4116 return index;
4117 }
4118
4119 public void moveAppToken(int index, IBinder token) {
4120 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4121 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004122 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004123 }
4124
4125 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004126 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 if (DEBUG_REORDER) dumpAppTokensLocked();
4128 final AppWindowToken wtoken = findAppWindowToken(token);
4129 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004130 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004131 + token + " (" + wtoken + ")");
4132 return;
4133 }
4134 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004135 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004139 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 if (DEBUG_REORDER) dumpWindowsLocked();
4141 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004142 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 if (DEBUG_REORDER) dumpWindowsLocked();
4144 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004145 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004146 if (DEBUG_REORDER) dumpWindowsLocked();
4147 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004148 mLayoutNeeded = true;
4149 performLayoutAndPlaceSurfacesLocked();
4150 }
4151 Binder.restoreCallingIdentity(origId);
4152 }
4153 }
4154
4155 private void removeAppTokensLocked(List<IBinder> tokens) {
4156 // XXX This should be done more efficiently!
4157 // (take advantage of the fact that both lists should be
4158 // ordered in the same way.)
4159 int N = tokens.size();
4160 for (int i=0; i<N; i++) {
4161 IBinder token = tokens.get(i);
4162 final AppWindowToken wtoken = findAppWindowToken(token);
4163 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004164 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 + token + " (" + wtoken + ")");
4166 i--;
4167 N--;
4168 }
4169 }
4170 }
4171
Dianne Hackborna8f60182009-09-01 19:01:50 -07004172 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4173 boolean updateFocusAndLayout) {
4174 // First remove all of the windows from the list.
4175 tmpRemoveAppWindowsLocked(wtoken);
4176
4177 // Where to start adding?
4178 int pos = findWindowOffsetLocked(tokenPos);
4179
4180 // And now add them back at the correct place.
4181 pos = reAddAppWindowsLocked(pos, wtoken);
4182
4183 if (updateFocusAndLayout) {
4184 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4185 assignLayersLocked();
4186 }
4187 mLayoutNeeded = true;
4188 performLayoutAndPlaceSurfacesLocked();
4189 }
4190 }
4191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4193 // First remove all of the windows from the list.
4194 final int N = tokens.size();
4195 int i;
4196 for (i=0; i<N; i++) {
4197 WindowToken token = mTokenMap.get(tokens.get(i));
4198 if (token != null) {
4199 tmpRemoveAppWindowsLocked(token);
4200 }
4201 }
4202
4203 // Where to start adding?
4204 int pos = findWindowOffsetLocked(tokenPos);
4205
4206 // And now add them back at the correct place.
4207 for (i=0; i<N; i++) {
4208 WindowToken token = mTokenMap.get(tokens.get(i));
4209 if (token != null) {
4210 pos = reAddAppWindowsLocked(pos, token);
4211 }
4212 }
4213
Dianne Hackborna8f60182009-09-01 19:01:50 -07004214 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4215 assignLayersLocked();
4216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 mLayoutNeeded = true;
4218 performLayoutAndPlaceSurfacesLocked();
4219
4220 //dump();
4221 }
4222
4223 public void moveAppTokensToTop(List<IBinder> tokens) {
4224 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4225 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004226 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004227 }
4228
4229 final long origId = Binder.clearCallingIdentity();
4230 synchronized(mWindowMap) {
4231 removeAppTokensLocked(tokens);
4232 final int N = tokens.size();
4233 for (int i=0; i<N; i++) {
4234 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4235 if (wt != null) {
4236 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004237 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004238 mToTopApps.remove(wt);
4239 mToBottomApps.remove(wt);
4240 mToTopApps.add(wt);
4241 wt.sendingToBottom = false;
4242 wt.sendingToTop = true;
4243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 }
4245 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004246
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004247 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004248 moveAppWindowsLocked(tokens, mAppTokens.size());
4249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 }
4251 Binder.restoreCallingIdentity(origId);
4252 }
4253
4254 public void moveAppTokensToBottom(List<IBinder> tokens) {
4255 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4256 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004257 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 }
4259
4260 final long origId = Binder.clearCallingIdentity();
4261 synchronized(mWindowMap) {
4262 removeAppTokensLocked(tokens);
4263 final int N = tokens.size();
4264 int pos = 0;
4265 for (int i=0; i<N; i++) {
4266 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4267 if (wt != null) {
4268 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004269 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004270 mToTopApps.remove(wt);
4271 mToBottomApps.remove(wt);
4272 mToBottomApps.add(i, wt);
4273 wt.sendingToTop = false;
4274 wt.sendingToBottom = true;
4275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 pos++;
4277 }
4278 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004279
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004280 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004281 moveAppWindowsLocked(tokens, 0);
4282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 }
4284 Binder.restoreCallingIdentity(origId);
4285 }
4286
4287 // -------------------------------------------------------------
4288 // Misc IWindowSession methods
4289 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004290
Jim Miller284b62e2010-06-08 14:27:42 -07004291 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004292 {
Jim Miller284b62e2010-06-08 14:27:42 -07004293 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4294 // called before DevicePolicyManagerService has started.
4295 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4296 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4297 Context.DEVICE_POLICY_SERVICE);
4298 if (dpm != null) {
4299 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4300 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4301 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4302 }
Jim Millerd6b57052010-06-07 17:52:42 -07004303 }
Jim Miller284b62e2010-06-08 14:27:42 -07004304 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004305 }
4306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004308 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004309 != PackageManager.PERMISSION_GRANTED) {
4310 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4311 }
Jim Millerd6b57052010-06-07 17:52:42 -07004312
Jim Miller284b62e2010-06-08 14:27:42 -07004313 synchronized (mKeyguardTokenWatcher) {
4314 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 }
4317
4318 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004319 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 != PackageManager.PERMISSION_GRANTED) {
4321 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323
Jim Miller284b62e2010-06-08 14:27:42 -07004324 synchronized (mKeyguardTokenWatcher) {
4325 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004326
Jim Miller284b62e2010-06-08 14:27:42 -07004327 if (!mKeyguardTokenWatcher.isAcquired()) {
4328 // If we are the last one to reenable the keyguard wait until
4329 // we have actually finished reenabling until returning.
4330 // It is possible that reenableKeyguard() can be called before
4331 // the previous disableKeyguard() is handled, in which case
4332 // neither mKeyguardTokenWatcher.acquired() or released() would
4333 // be called. In that case mKeyguardDisabled will be false here
4334 // and we have nothing to wait for.
4335 while (mKeyguardDisabled) {
4336 try {
4337 mKeyguardTokenWatcher.wait();
4338 } catch (InterruptedException e) {
4339 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 }
4341 }
4342 }
4343 }
4344 }
4345
4346 /**
4347 * @see android.app.KeyguardManager#exitKeyguardSecurely
4348 */
4349 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004350 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 != PackageManager.PERMISSION_GRANTED) {
4352 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4353 }
4354 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4355 public void onKeyguardExitResult(boolean success) {
4356 try {
4357 callback.onKeyguardExitResult(success);
4358 } catch (RemoteException e) {
4359 // Client has died, we don't care.
4360 }
4361 }
4362 });
4363 }
4364
4365 public boolean inKeyguardRestrictedInputMode() {
4366 return mPolicy.inKeyguardRestrictedKeyInputMode();
4367 }
Romain Guy06882f82009-06-10 13:36:04 -07004368
Dianne Hackbornffa42482009-09-23 22:20:11 -07004369 public void closeSystemDialogs(String reason) {
4370 synchronized(mWindowMap) {
4371 for (int i=mWindows.size()-1; i>=0; i--) {
4372 WindowState w = (WindowState)mWindows.get(i);
4373 if (w.mSurface != null) {
4374 try {
4375 w.mClient.closeSystemDialogs(reason);
4376 } catch (RemoteException e) {
4377 }
4378 }
4379 }
4380 }
4381 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 static float fixScale(float scale) {
4384 if (scale < 0) scale = 0;
4385 else if (scale > 20) scale = 20;
4386 return Math.abs(scale);
4387 }
Romain Guy06882f82009-06-10 13:36:04 -07004388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 public void setAnimationScale(int which, float scale) {
4390 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4391 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004392 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 }
4394
4395 if (scale < 0) scale = 0;
4396 else if (scale > 20) scale = 20;
4397 scale = Math.abs(scale);
4398 switch (which) {
4399 case 0: mWindowAnimationScale = fixScale(scale); break;
4400 case 1: mTransitionAnimationScale = fixScale(scale); break;
4401 }
Romain Guy06882f82009-06-10 13:36:04 -07004402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 // Persist setting
4404 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4405 }
Romain Guy06882f82009-06-10 13:36:04 -07004406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 public void setAnimationScales(float[] scales) {
4408 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4409 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004410 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 }
4412
4413 if (scales != null) {
4414 if (scales.length >= 1) {
4415 mWindowAnimationScale = fixScale(scales[0]);
4416 }
4417 if (scales.length >= 2) {
4418 mTransitionAnimationScale = fixScale(scales[1]);
4419 }
4420 }
Romain Guy06882f82009-06-10 13:36:04 -07004421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 // Persist setting
4423 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4424 }
Romain Guy06882f82009-06-10 13:36:04 -07004425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 public float getAnimationScale(int which) {
4427 switch (which) {
4428 case 0: return mWindowAnimationScale;
4429 case 1: return mTransitionAnimationScale;
4430 }
4431 return 0;
4432 }
Romain Guy06882f82009-06-10 13:36:04 -07004433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 public float[] getAnimationScales() {
4435 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4436 }
Romain Guy06882f82009-06-10 13:36:04 -07004437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 public int getSwitchState(int sw) {
4439 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4440 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004441 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004443 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4444 return mInputManager.getSwitchState(sw);
4445 } else {
4446 return KeyInputQueue.getSwitchState(sw);
4447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 }
Romain Guy06882f82009-06-10 13:36:04 -07004449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 public int getSwitchStateForDevice(int devid, int sw) {
4451 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4452 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004453 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004455 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4456 return mInputManager.getSwitchState(devid, sw);
4457 } else {
4458 return KeyInputQueue.getSwitchState(devid, sw);
4459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 }
Romain Guy06882f82009-06-10 13:36:04 -07004461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 public int getScancodeState(int sw) {
4463 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4464 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004465 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004467 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4468 return mInputManager.getScancodeState(sw);
4469 } else {
4470 return mQueue.getScancodeState(sw);
4471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 }
Romain Guy06882f82009-06-10 13:36:04 -07004473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 public int getScancodeStateForDevice(int devid, int sw) {
4475 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4476 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004477 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004479 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4480 return mInputManager.getScancodeState(devid, sw);
4481 } else {
4482 return mQueue.getScancodeState(devid, sw);
4483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 }
Romain Guy06882f82009-06-10 13:36:04 -07004485
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004486 public int getTrackballScancodeState(int sw) {
4487 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4488 "getTrackballScancodeState()")) {
4489 throw new SecurityException("Requires READ_INPUT_STATE permission");
4490 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004491 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4492 return mInputManager.getTrackballScancodeState(sw);
4493 } else {
4494 return mQueue.getTrackballScancodeState(sw);
4495 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004496 }
4497
4498 public int getDPadScancodeState(int sw) {
4499 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4500 "getDPadScancodeState()")) {
4501 throw new SecurityException("Requires READ_INPUT_STATE permission");
4502 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004503 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4504 return mInputManager.getDPadScancodeState(sw);
4505 } else {
4506 return mQueue.getDPadScancodeState(sw);
4507 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004508 }
4509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 public int getKeycodeState(int sw) {
4511 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4512 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004513 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004515 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4516 return mInputManager.getKeycodeState(sw);
4517 } else {
4518 return mQueue.getKeycodeState(sw);
4519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 }
Romain Guy06882f82009-06-10 13:36:04 -07004521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522 public int getKeycodeStateForDevice(int devid, int sw) {
4523 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4524 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004525 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004527 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4528 return mInputManager.getKeycodeState(devid, sw);
4529 } else {
4530 return mQueue.getKeycodeState(devid, sw);
4531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 }
Romain Guy06882f82009-06-10 13:36:04 -07004533
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004534 public int getTrackballKeycodeState(int sw) {
4535 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4536 "getTrackballKeycodeState()")) {
4537 throw new SecurityException("Requires READ_INPUT_STATE permission");
4538 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004539 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4540 return mInputManager.getTrackballKeycodeState(sw);
4541 } else {
4542 return mQueue.getTrackballKeycodeState(sw);
4543 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004544 }
4545
4546 public int getDPadKeycodeState(int sw) {
4547 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4548 "getDPadKeycodeState()")) {
4549 throw new SecurityException("Requires READ_INPUT_STATE permission");
4550 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004551 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4552 return mInputManager.getDPadKeycodeState(sw);
4553 } else {
4554 return mQueue.getDPadKeycodeState(sw);
4555 }
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004556 }
4557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004559 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4560 return mInputManager.hasKeys(keycodes, keyExists);
4561 } else {
4562 return KeyInputQueue.hasKeys(keycodes, keyExists);
4563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 }
Romain Guy06882f82009-06-10 13:36:04 -07004565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 public void enableScreenAfterBoot() {
4567 synchronized(mWindowMap) {
4568 if (mSystemBooted) {
4569 return;
4570 }
4571 mSystemBooted = true;
4572 }
Romain Guy06882f82009-06-10 13:36:04 -07004573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 performEnableScreen();
4575 }
Romain Guy06882f82009-06-10 13:36:04 -07004576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 public void enableScreenIfNeededLocked() {
4578 if (mDisplayEnabled) {
4579 return;
4580 }
4581 if (!mSystemBooted) {
4582 return;
4583 }
4584 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4585 }
Romain Guy06882f82009-06-10 13:36:04 -07004586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004587 public void performEnableScreen() {
4588 synchronized(mWindowMap) {
4589 if (mDisplayEnabled) {
4590 return;
4591 }
4592 if (!mSystemBooted) {
4593 return;
4594 }
Romain Guy06882f82009-06-10 13:36:04 -07004595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 // Don't enable the screen until all existing windows
4597 // have been drawn.
4598 final int N = mWindows.size();
4599 for (int i=0; i<N; i++) {
4600 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004601 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 return;
4603 }
4604 }
Romain Guy06882f82009-06-10 13:36:04 -07004605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 mDisplayEnabled = true;
4607 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004608 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 StringWriter sw = new StringWriter();
4610 PrintWriter pw = new PrintWriter(sw);
4611 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004612 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 }
4614 try {
4615 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4616 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004617 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 Parcel data = Parcel.obtain();
4619 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4620 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4621 data, null, 0);
4622 data.recycle();
4623 }
4624 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004625 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627 }
Romain Guy06882f82009-06-10 13:36:04 -07004628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004632 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4633 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
Romain Guy06882f82009-06-10 13:36:04 -07004635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 public void setInTouchMode(boolean mode) {
4637 synchronized(mWindowMap) {
4638 mInTouchMode = mode;
4639 }
4640 }
4641
Romain Guy06882f82009-06-10 13:36:04 -07004642 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004643 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004644 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004645 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004646 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
4648
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004649 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
Romain Guy06882f82009-06-10 13:36:04 -07004651
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004652 public void setRotationUnchecked(int rotation,
4653 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004654 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 long origId = Binder.clearCallingIdentity();
4658 boolean changed;
4659 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004660 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 }
Romain Guy06882f82009-06-10 13:36:04 -07004662
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004663 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 sendNewConfiguration();
4665 }
Romain Guy06882f82009-06-10 13:36:04 -07004666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 Binder.restoreCallingIdentity(origId);
4668 }
Romain Guy06882f82009-06-10 13:36:04 -07004669
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004670 /**
4671 * Apply a new rotation to the screen, respecting the requests of
4672 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4673 * re-evaluate the desired rotation.
4674 *
4675 * Returns null if the rotation has been changed. In this case YOU
4676 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4677 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004678 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 boolean changed;
4680 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4681 rotation = mRequestedRotation;
4682 } else {
4683 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004684 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004686 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004687 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004689 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004693 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 "Rotation changed to " + rotation
4695 + " from " + mRotation
4696 + " (forceApp=" + mForcedAppOrientation
4697 + ", req=" + mRequestedRotation + ")");
4698 mRotation = rotation;
4699 mWindowsFreezingScreen = true;
4700 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4701 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4702 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004703 mWaitingForConfig = true;
4704 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004706 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004707 if (ENABLE_NATIVE_INPUT_DISPATCH) {
4708 mInputManager.setDisplayOrientation(0, rotation);
4709 } else {
4710 mQueue.setOrientation(rotation);
4711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004713 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004714 }
4715 for (int i=mWindows.size()-1; i>=0; i--) {
4716 WindowState w = (WindowState)mWindows.get(i);
4717 if (w.mSurface != null) {
4718 w.mOrientationChanging = true;
4719 }
4720 }
4721 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4722 try {
4723 mRotationWatchers.get(i).onRotationChanged(rotation);
4724 } catch (RemoteException e) {
4725 }
4726 }
4727 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 return changed;
4730 }
Romain Guy06882f82009-06-10 13:36:04 -07004731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 public int getRotation() {
4733 return mRotation;
4734 }
4735
4736 public int watchRotation(IRotationWatcher watcher) {
4737 final IBinder watcherBinder = watcher.asBinder();
4738 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4739 public void binderDied() {
4740 synchronized (mWindowMap) {
4741 for (int i=0; i<mRotationWatchers.size(); i++) {
4742 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004743 IRotationWatcher removed = mRotationWatchers.remove(i);
4744 if (removed != null) {
4745 removed.asBinder().unlinkToDeath(this, 0);
4746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 i--;
4748 }
4749 }
4750 }
4751 }
4752 };
Romain Guy06882f82009-06-10 13:36:04 -07004753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 synchronized (mWindowMap) {
4755 try {
4756 watcher.asBinder().linkToDeath(dr, 0);
4757 mRotationWatchers.add(watcher);
4758 } catch (RemoteException e) {
4759 // Client died, no cleanup needed.
4760 }
Romain Guy06882f82009-06-10 13:36:04 -07004761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 return mRotation;
4763 }
4764 }
4765
4766 /**
4767 * Starts the view server on the specified port.
4768 *
4769 * @param port The port to listener to.
4770 *
4771 * @return True if the server was successfully started, false otherwise.
4772 *
4773 * @see com.android.server.ViewServer
4774 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4775 */
4776 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004777 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 return false;
4779 }
4780
4781 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4782 return false;
4783 }
4784
4785 if (port < 1024) {
4786 return false;
4787 }
4788
4789 if (mViewServer != null) {
4790 if (!mViewServer.isRunning()) {
4791 try {
4792 return mViewServer.start();
4793 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004794 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 }
4796 }
4797 return false;
4798 }
4799
4800 try {
4801 mViewServer = new ViewServer(this, port);
4802 return mViewServer.start();
4803 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004804 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 }
4806 return false;
4807 }
4808
Romain Guy06882f82009-06-10 13:36:04 -07004809 private boolean isSystemSecure() {
4810 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4811 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4812 }
4813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 /**
4815 * Stops the view server if it exists.
4816 *
4817 * @return True if the server stopped, false if it wasn't started or
4818 * couldn't be stopped.
4819 *
4820 * @see com.android.server.ViewServer
4821 */
4822 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004823 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 return false;
4825 }
4826
4827 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4828 return false;
4829 }
4830
4831 if (mViewServer != null) {
4832 return mViewServer.stop();
4833 }
4834 return false;
4835 }
4836
4837 /**
4838 * Indicates whether the view server is running.
4839 *
4840 * @return True if the server is running, false otherwise.
4841 *
4842 * @see com.android.server.ViewServer
4843 */
4844 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004845 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 return false;
4847 }
4848
4849 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4850 return false;
4851 }
4852
4853 return mViewServer != null && mViewServer.isRunning();
4854 }
4855
4856 /**
4857 * Lists all availble windows in the system. The listing is written in the
4858 * specified Socket's output stream with the following syntax:
4859 * windowHashCodeInHexadecimal windowName
4860 * Each line of the ouput represents a different window.
4861 *
4862 * @param client The remote client to send the listing to.
4863 * @return False if an error occured, true otherwise.
4864 */
4865 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07004866 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 return false;
4868 }
4869
4870 boolean result = true;
4871
4872 Object[] windows;
4873 synchronized (mWindowMap) {
4874 windows = new Object[mWindows.size()];
4875 //noinspection unchecked
4876 windows = mWindows.toArray(windows);
4877 }
4878
4879 BufferedWriter out = null;
4880
4881 // Any uncaught exception will crash the system process
4882 try {
4883 OutputStream clientStream = client.getOutputStream();
4884 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4885
4886 final int count = windows.length;
4887 for (int i = 0; i < count; i++) {
4888 final WindowState w = (WindowState) windows[i];
4889 out.write(Integer.toHexString(System.identityHashCode(w)));
4890 out.write(' ');
4891 out.append(w.mAttrs.getTitle());
4892 out.write('\n');
4893 }
4894
4895 out.write("DONE.\n");
4896 out.flush();
4897 } catch (Exception e) {
4898 result = false;
4899 } finally {
4900 if (out != null) {
4901 try {
4902 out.close();
4903 } catch (IOException e) {
4904 result = false;
4905 }
4906 }
4907 }
4908
4909 return result;
4910 }
4911
4912 /**
4913 * Sends a command to a target window. The result of the command, if any, will be
4914 * written in the output stream of the specified socket.
4915 *
4916 * The parameters must follow this syntax:
4917 * windowHashcode extra
4918 *
4919 * Where XX is the length in characeters of the windowTitle.
4920 *
4921 * The first parameter is the target window. The window with the specified hashcode
4922 * will be the target. If no target can be found, nothing happens. The extra parameters
4923 * will be delivered to the target window and as parameters to the command itself.
4924 *
4925 * @param client The remote client to sent the result, if any, to.
4926 * @param command The command to execute.
4927 * @param parameters The command parameters.
4928 *
4929 * @return True if the command was successfully delivered, false otherwise. This does
4930 * not indicate whether the command itself was successful.
4931 */
4932 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07004933 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 return false;
4935 }
4936
4937 boolean success = true;
4938 Parcel data = null;
4939 Parcel reply = null;
4940
4941 // Any uncaught exception will crash the system process
4942 try {
4943 // Find the hashcode of the window
4944 int index = parameters.indexOf(' ');
4945 if (index == -1) {
4946 index = parameters.length();
4947 }
4948 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08004949 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950
4951 // Extract the command's parameter after the window description
4952 if (index < parameters.length()) {
4953 parameters = parameters.substring(index + 1);
4954 } else {
4955 parameters = "";
4956 }
4957
4958 final WindowManagerService.WindowState window = findWindow(hashCode);
4959 if (window == null) {
4960 return false;
4961 }
4962
4963 data = Parcel.obtain();
4964 data.writeInterfaceToken("android.view.IWindow");
4965 data.writeString(command);
4966 data.writeString(parameters);
4967 data.writeInt(1);
4968 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4969
4970 reply = Parcel.obtain();
4971
4972 final IBinder binder = window.mClient.asBinder();
4973 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4974 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4975
4976 reply.readException();
4977
4978 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004979 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 success = false;
4981 } finally {
4982 if (data != null) {
4983 data.recycle();
4984 }
4985 if (reply != null) {
4986 reply.recycle();
4987 }
4988 }
4989
4990 return success;
4991 }
4992
4993 private WindowState findWindow(int hashCode) {
4994 if (hashCode == -1) {
4995 return getFocusedWindow();
4996 }
4997
4998 synchronized (mWindowMap) {
4999 final ArrayList windows = mWindows;
5000 final int count = windows.size();
5001
5002 for (int i = 0; i < count; i++) {
5003 WindowState w = (WindowState) windows.get(i);
5004 if (System.identityHashCode(w) == hashCode) {
5005 return w;
5006 }
5007 }
5008 }
5009
5010 return null;
5011 }
5012
5013 /*
5014 * Instruct the Activity Manager to fetch the current configuration and broadcast
5015 * that to config-changed listeners if appropriate.
5016 */
5017 void sendNewConfiguration() {
5018 try {
5019 mActivityManager.updateConfiguration(null);
5020 } catch (RemoteException e) {
5021 }
5022 }
Romain Guy06882f82009-06-10 13:36:04 -07005023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 public Configuration computeNewConfiguration() {
5025 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005026 return computeNewConfigurationLocked();
5027 }
5028 }
Romain Guy06882f82009-06-10 13:36:04 -07005029
Dianne Hackbornc485a602009-03-24 22:39:49 -07005030 Configuration computeNewConfigurationLocked() {
5031 Configuration config = new Configuration();
5032 if (!computeNewConfigurationLocked(config)) {
5033 return null;
5034 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005035 return config;
5036 }
Romain Guy06882f82009-06-10 13:36:04 -07005037
Dianne Hackbornc485a602009-03-24 22:39:49 -07005038 boolean computeNewConfigurationLocked(Configuration config) {
5039 if (mDisplay == null) {
5040 return false;
5041 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005042 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5043 mInputManager.getInputConfiguration(config);
5044 } else {
5045 mQueue.getInputConfiguration(config);
5046 }
Christopher Tateb696aee2010-04-02 19:08:30 -07005047
5048 // Use the effective "visual" dimensions based on current rotation
5049 final boolean rotated = (mRotation == Surface.ROTATION_90
5050 || mRotation == Surface.ROTATION_270);
5051 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5052 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5053
Dianne Hackbornc485a602009-03-24 22:39:49 -07005054 int orientation = Configuration.ORIENTATION_SQUARE;
5055 if (dw < dh) {
5056 orientation = Configuration.ORIENTATION_PORTRAIT;
5057 } else if (dw > dh) {
5058 orientation = Configuration.ORIENTATION_LANDSCAPE;
5059 }
5060 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005061
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005062 DisplayMetrics dm = new DisplayMetrics();
5063 mDisplay.getMetrics(dm);
5064 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5065
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005066 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005067 // Note we only do this once because at this point we don't
5068 // expect the screen to change in this way at runtime, and want
5069 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005070 int longSize = dw;
5071 int shortSize = dh;
5072 if (longSize < shortSize) {
5073 int tmp = longSize;
5074 longSize = shortSize;
5075 shortSize = tmp;
5076 }
5077 longSize = (int)(longSize/dm.density);
5078 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005079
Dianne Hackborn723738c2009-06-25 19:48:04 -07005080 // These semi-magic numbers define our compatibility modes for
5081 // applications with different screens. Don't change unless you
5082 // make sure to test lots and lots of apps!
5083 if (longSize < 470) {
5084 // This is shorter than an HVGA normal density screen (which
5085 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005086 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5087 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005088 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005089 // What size is this screen screen?
5090 if (longSize >= 800 && shortSize >= 600) {
5091 // SVGA or larger screens at medium density are the point
5092 // at which we consider it to be an extra large screen.
5093 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5094 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005095 // VGA or larger screens at medium density are the point
5096 // at which we consider it to be a large screen.
5097 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5098 } else {
5099 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005100
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005101 // If this screen is wider than normal HVGA, or taller
5102 // than FWVGA, then for old apps we want to run in size
5103 // compatibility mode.
5104 if (shortSize > 321 || longSize > 570) {
5105 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5106 }
5107 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005108
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005109 // Is this a long screen?
5110 if (((longSize*3)/5) >= (shortSize-1)) {
5111 // Anything wider than WVGA (5:3) is considering to be long.
5112 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5113 } else {
5114 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5115 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005116 }
5117 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005118 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005119
Dianne Hackbornc485a602009-03-24 22:39:49 -07005120 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5121 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5122 mPolicy.adjustConfigurationLw(config);
5123 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 // -------------------------------------------------------------
5127 // Input Events and Focus Management
5128 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005129
Jeff Brown349703e2010-06-22 01:27:15 -07005130 InputMonitor mInputMonitor = new InputMonitor();
5131
5132 /* Tracks the progress of input dispatch and ensures that input dispatch state
5133 * is kept in sync with changes in window focus, visibility, registration, and
5134 * other relevant Window Manager state transitions. */
5135 final class InputMonitor {
5136 // Current window with input focus for keys and other non-touch events. May be null.
5137 private WindowState mInputFocus;
5138
5139 // When true, prevents input dispatch from proceeding until set to false again.
5140 private boolean mInputDispatchFrozen;
5141
5142 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5143 private boolean mInputDispatchEnabled = true;
5144
5145 // Temporary list of windows information to provide to the input dispatcher.
5146 private InputWindowList mTempInputWindows = new InputWindowList();
5147
5148 // Temporary input application object to provide to the input dispatcher.
5149 private InputApplication mTempInputApplication = new InputApplication();
5150
5151 /* Notifies the window manager about a broken input channel.
5152 *
5153 * Called by the InputManager.
5154 */
5155 public void notifyInputChannelBroken(InputChannel inputChannel) {
5156 synchronized (mWindowMap) {
5157 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5158 if (windowState == null) {
5159 return; // irrelevant
5160 }
5161
5162 Slog.i(TAG, "WINDOW DIED " + windowState);
5163 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005164 }
5165 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005166
Jeff Brown349703e2010-06-22 01:27:15 -07005167 /* Notifies the window manager about an input channel that is not responding.
5168 * The method can either cause dispatching to be aborted by returning -2 or
5169 * return a new timeout in nanoseconds.
5170 *
5171 * Called by the InputManager.
5172 */
5173 public long notifyInputChannelANR(InputChannel inputChannel) {
5174 AppWindowToken token;
5175 synchronized (mWindowMap) {
5176 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5177 if (windowState == null) {
5178 return -2; // irrelevant, abort dispatching (-2)
5179 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005180
Jeff Brown349703e2010-06-22 01:27:15 -07005181 Slog.i(TAG, "Input event dispatching timed out sending to "
5182 + windowState.mAttrs.getTitle());
5183 token = windowState.mAppToken;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005184 }
5185
Jeff Brown349703e2010-06-22 01:27:15 -07005186 return notifyANRInternal(token);
5187 }
5188
5189 /* Notifies the window manager about an input channel spontaneously recovering from ANR
5190 * by successfully delivering the event that originally timed out.
5191 *
5192 * Called by the InputManager.
5193 */
5194 public void notifyInputChannelRecoveredFromANR(InputChannel inputChannel) {
5195 // Nothing to do just now.
5196 // Just wait for the user to dismiss the ANR dialog.
5197 }
5198
5199 /* Notifies the window manager about an application that is not responding
5200 * in general rather than with respect to a particular input channel.
5201 * The method can either cause dispatching to be aborted by returning -2 or
5202 * return a new timeout in nanoseconds.
5203 *
5204 * Called by the InputManager.
5205 */
5206 public long notifyANR(Object token) {
5207 AppWindowToken appWindowToken = (AppWindowToken) token;
5208
5209 Slog.i(TAG, "Input event dispatching timed out sending to application "
5210 + appWindowToken.stringName);
5211 return notifyANRInternal(appWindowToken);
5212 }
5213
5214 private long notifyANRInternal(AppWindowToken token) {
5215 if (token != null && token.appToken != null) {
5216 try {
5217 // Notify the activity manager about the timeout and let it decide whether
5218 // to abort dispatching or keep waiting.
5219 boolean abort = token.appToken.keyDispatchingTimedOut();
5220 if (! abort) {
5221 // The activity manager declined to abort dispatching.
5222 // Wait a bit longer and timeout again later.
5223 return token.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005224 }
Jeff Brown349703e2010-06-22 01:27:15 -07005225 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005226 }
5227 }
Jeff Brown349703e2010-06-22 01:27:15 -07005228 return -2; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005229 }
5230
Jeff Brown349703e2010-06-22 01:27:15 -07005231 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5232 synchronized (mWindowMap) {
5233 return getWindowStateForInputChannelLocked(inputChannel);
5234 }
5235 }
5236
5237 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5238 int windowCount = mWindows.size();
5239 for (int i = 0; i < windowCount; i++) {
5240 WindowState windowState = (WindowState) mWindows.get(i);
5241 if (windowState.mInputChannel == inputChannel) {
5242 return windowState;
5243 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005244 }
5245
Jeff Brown349703e2010-06-22 01:27:15 -07005246 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005247 }
5248
Jeff Brown349703e2010-06-22 01:27:15 -07005249 /* Updates the cached window information provided to the input dispatcher. */
5250 public void updateInputWindowsLw() {
5251 // Populate the input window list with information about all of the windows that
5252 // could potentially receive input.
5253 // As an optimization, we could try to prune the list of windows but this turns
5254 // out to be difficult because only the native code knows for sure which window
5255 // currently has touch focus.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005256 final ArrayList windows = mWindows;
5257 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005258 for (int i = N - 1; i >= 0; i--) {
5259 final WindowState child = (WindowState) windows.get(i);
5260 if (child.mInputChannel == null) {
5261 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005262 continue;
5263 }
5264
Jeff Brown349703e2010-06-22 01:27:15 -07005265 final int flags = child.mAttrs.flags;
5266 final int type = child.mAttrs.type;
5267
5268 final boolean hasFocus = (child == mInputFocus);
5269 final boolean isVisible = child.isVisibleLw();
5270 final boolean hasWallpaper = (child == mWallpaperTarget)
5271 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
5272
5273 // Add a window to our list of input windows.
5274 final InputWindow inputWindow = mTempInputWindows.add();
5275 inputWindow.inputChannel = child.mInputChannel;
5276 inputWindow.layoutParamsFlags = flags;
5277 inputWindow.layoutParamsType = type;
5278 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5279 inputWindow.visible = isVisible;
5280 inputWindow.hasFocus = hasFocus;
5281 inputWindow.hasWallpaper = hasWallpaper;
5282 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
5283 inputWindow.ownerPid = child.mSession.mPid;
5284 inputWindow.ownerUid = child.mSession.mUid;
5285
5286 final Rect frame = child.mFrame;
5287 inputWindow.frameLeft = frame.left;
5288 inputWindow.frameTop = frame.top;
5289
5290 switch (child.mTouchableInsets) {
5291 default:
5292 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5293 inputWindow.touchableAreaLeft = frame.left;
5294 inputWindow.touchableAreaTop = frame.top;
5295 inputWindow.touchableAreaRight = frame.right;
5296 inputWindow.touchableAreaBottom = frame.bottom;
5297 break;
5298
5299 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5300 Rect inset = child.mGivenContentInsets;
5301 inputWindow.touchableAreaLeft = frame.left + inset.left;
5302 inputWindow.touchableAreaTop = frame.top + inset.top;
5303 inputWindow.touchableAreaRight = frame.right - inset.right;
5304 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5305 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005306 }
Jeff Brown349703e2010-06-22 01:27:15 -07005307
5308 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5309 Rect inset = child.mGivenVisibleInsets;
5310 inputWindow.touchableAreaLeft = frame.left + inset.left;
5311 inputWindow.touchableAreaTop = frame.top + inset.top;
5312 inputWindow.touchableAreaRight = frame.right - inset.right;
5313 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005314 break;
5315 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005316 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005317 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005318
Jeff Brown349703e2010-06-22 01:27:15 -07005319 // Send windows to native code.
5320 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005321
Jeff Brown349703e2010-06-22 01:27:15 -07005322 // Clear the list in preparation for the next round.
5323 // Also avoids keeping InputChannel objects referenced unnecessarily.
5324 mTempInputWindows.clear();
5325 }
5326
5327 /* Notifies that an app switch key (BACK / HOME) has just been pressed.
5328 * This essentially starts a .5 second timeout for the application to process
5329 * subsequent input events while waiting for the app switch to occur. If it takes longer
5330 * than this, the pending events will be dropped.
5331 */
5332 public void notifyAppSwitchComing() {
5333 // TODO Not implemented yet. Should go in the native side.
5334 }
5335
5336 /* Provides an opportunity for the window manager policy to intercept early key
5337 * processing as soon as the key has been read from the device. */
5338 public int interceptKeyBeforeQueueing(int deviceId, int type, int scanCode,
5339 int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) {
5340 RawInputEvent event = new RawInputEvent();
5341 event.deviceId = deviceId;
5342 event.type = type;
5343 event.scancode = scanCode;
5344 event.keycode = keyCode;
5345 event.flags = policyFlags;
5346 event.value = value;
5347 event.when = whenNanos / 1000000;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005348
Jeff Brown349703e2010-06-22 01:27:15 -07005349 return mPolicy.interceptKeyTq(event, isScreenOn);
5350 }
5351
5352 /* Provides an opportunity for the window manager policy to process a key before
5353 * ordinary dispatch. */
5354 public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode,
5355 int metaState, boolean down, int repeatCount, int policyFlags) {
5356 WindowState windowState = getWindowStateForInputChannel(focus);
5357 return mPolicy.interceptKeyTi(windowState, keyCode, metaState, down, repeatCount,
5358 policyFlags);
5359 }
5360
5361 /* Called when the current input focus changes.
5362 * Layer assignment is assumed to be complete by the time this is called.
5363 */
5364 public void setInputFocusLw(WindowState newWindow) {
5365 if (DEBUG_INPUT) {
5366 Slog.d(TAG, "Input focus has changed to " + newWindow);
5367 }
5368
5369 if (newWindow != mInputFocus) {
5370 if (newWindow != null && newWindow.canReceiveKeys()) {
5371 // If the new input focus is an error window or appears above the current
5372 // input focus, preempt any pending synchronous dispatch so that we can
5373 // start delivering events to the new input focus as soon as possible.
5374 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
5375 if (DEBUG_INPUT) {
5376 Slog.v(TAG, "New SYSTEM_ERROR window; resetting state");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005377 }
Jeff Brown349703e2010-06-22 01:27:15 -07005378 preemptInputDispatchLw();
5379 } else if (mInputFocus != null && newWindow.mLayer > mInputFocus.mLayer) {
5380 if (DEBUG_INPUT) {
5381 Slog.v(TAG, "Transferring focus to new window at higher layer: "
5382 + "old win layer=" + mInputFocus.mLayer
5383 + ", new win layer=" + newWindow.mLayer);
5384 }
5385 preemptInputDispatchLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005386 }
Jeff Brown349703e2010-06-22 01:27:15 -07005387
5388 // Displaying a window implicitly causes dispatching to be unpaused.
5389 // This is to protect against bugs if someone pauses dispatching but
5390 // forgets to resume.
5391 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005392 }
Jeff Brown349703e2010-06-22 01:27:15 -07005393
5394 mInputFocus = newWindow;
5395 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005396 }
5397 }
5398
Jeff Brown349703e2010-06-22 01:27:15 -07005399 public void windowIsBecomingInvisibleLw(WindowState window) {
5400 // The window is becoming invisible. Preempt input dispatch in progress
5401 // so that the next window below can receive focus.
5402 if (window == mInputFocus) {
5403 mInputFocus = null;
5404 preemptInputDispatchLw();
5405 }
5406
5407 updateInputWindowsLw();
5408 }
5409
5410 /* Tells the dispatcher to stop waiting for its current synchronous event targets.
5411 * Essentially, just makes those dispatches asynchronous so a new dispatch cycle
5412 * can begin.
5413 */
5414 private void preemptInputDispatchLw() {
5415 mInputManager.preemptInputDispatch();
5416 }
5417
5418 public void setFocusedAppLw(AppWindowToken newApp) {
5419 // Focused app has changed.
5420 if (newApp == null) {
5421 mInputManager.setFocusedApplication(null);
5422 } else {
5423 mTempInputApplication.name = newApp.toString();
5424 mTempInputApplication.dispatchingTimeoutNanos =
5425 newApp.inputDispatchingTimeoutNanos;
5426 mTempInputApplication.token = newApp;
5427
5428 mInputManager.setFocusedApplication(mTempInputApplication);
5429 }
5430 }
5431
5432 public void windowIsBeingRemovedLw(WindowState window) {
5433 // Window is being removed.
5434 updateInputWindowsLw();
5435 }
5436
5437 public void pauseDispatchingLw(WindowToken window) {
5438 if (! window.paused) {
5439 if (DEBUG_INPUT) {
5440 Slog.v(TAG, "Pausing WindowToken " + window);
5441 }
5442
5443 window.paused = true;
5444 updateInputWindowsLw();
5445 }
5446 }
5447
5448 public void resumeDispatchingLw(WindowToken window) {
5449 if (window.paused) {
5450 if (DEBUG_INPUT) {
5451 Slog.v(TAG, "Resuming WindowToken " + window);
5452 }
5453
5454 window.paused = false;
5455 updateInputWindowsLw();
5456 }
5457 }
5458
5459 public void freezeInputDispatchingLw() {
5460 if (! mInputDispatchFrozen) {
5461 if (DEBUG_INPUT) {
5462 Slog.v(TAG, "Freezing input dispatching");
5463 }
5464
5465 mInputDispatchFrozen = true;
5466 updateInputDispatchModeLw();
5467 }
5468 }
5469
5470 public void thawInputDispatchingLw() {
5471 if (mInputDispatchFrozen) {
5472 if (DEBUG_INPUT) {
5473 Slog.v(TAG, "Thawing input dispatching");
5474 }
5475
5476 mInputDispatchFrozen = false;
5477 updateInputDispatchModeLw();
5478 }
5479 }
5480
5481 public void setEventDispatchingLw(boolean enabled) {
5482 if (mInputDispatchEnabled != enabled) {
5483 if (DEBUG_INPUT) {
5484 Slog.v(TAG, "Setting event dispatching to " + enabled);
5485 }
5486
5487 mInputDispatchEnabled = enabled;
5488 updateInputDispatchModeLw();
5489 }
5490 }
5491
5492 private void updateInputDispatchModeLw() {
5493 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5494 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496
5497 private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
Michael Chane96440f2009-05-06 10:27:36 -07005498 long curTime = SystemClock.uptimeMillis();
5499
Michael Chane10de972009-05-18 11:24:50 -07005500 if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
Michael Chane96440f2009-05-06 10:27:36 -07005501 if (mLastTouchEventType == eventType &&
5502 (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
5503 return;
5504 }
5505 mLastUserActivityCallTime = curTime;
5506 mLastTouchEventType = eventType;
5507 }
5508
5509 if (targetWin == null
5510 || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
5511 mPowerManager.userActivity(curTime, false, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512 }
5513 }
5514
5515 // tells if it's a cheek event or not -- this function is stateful
5516 private static final int EVENT_NONE = 0;
5517 private static final int EVENT_UNKNOWN = 0;
5518 private static final int EVENT_CHEEK = 0;
5519 private static final int EVENT_IGNORE_DURATION = 300; // ms
5520 private static final float CHEEK_THRESHOLD = 0.6f;
5521 private int mEventState = EVENT_NONE;
5522 private float mEventSize;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005524 private int eventType(MotionEvent ev) {
5525 float size = ev.getSize();
5526 switch (ev.getAction()) {
5527 case MotionEvent.ACTION_DOWN:
5528 mEventSize = size;
5529 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
5530 case MotionEvent.ACTION_UP:
5531 if (size > mEventSize) mEventSize = size;
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005532 return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 case MotionEvent.ACTION_MOVE:
5534 final int N = ev.getHistorySize();
5535 if (size > mEventSize) mEventSize = size;
5536 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5537 for (int i=0; i<N; i++) {
5538 size = ev.getHistoricalSize(i);
5539 if (size > mEventSize) mEventSize = size;
5540 if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
5541 }
5542 if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
5543 return TOUCH_EVENT;
5544 } else {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07005545 return LONG_TOUCH_EVENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005546 }
5547 default:
5548 // not good
5549 return OTHER_EVENT;
5550 }
5551 }
Jeff Brown349703e2010-06-22 01:27:15 -07005552
5553 private boolean mFatTouch; // remove me together with dispatchPointer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005554
5555 /**
5556 * @return Returns true if event was dispatched, false if it was dropped for any reason
5557 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005558 private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005559 if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 "dispatchPointer " + ev);
5561
Michael Chan53071d62009-05-13 17:29:48 -07005562 if (MEASURE_LATENCY) {
5563 lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
5564 }
5565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005567 ev, true, false, pid, uid);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005568
Michael Chan53071d62009-05-13 17:29:48 -07005569 if (MEASURE_LATENCY) {
5570 lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
5571 }
5572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 int action = ev.getAction();
Romain Guy06882f82009-06-10 13:36:04 -07005574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 if (action == MotionEvent.ACTION_UP) {
5576 // let go of our target
5577 mKeyWaiter.mMotionTarget = null;
5578 mPowerManager.logPointerUpEvent();
5579 } else if (action == MotionEvent.ACTION_DOWN) {
5580 mPowerManager.logPointerDownEvent();
5581 }
5582
5583 if (targetObj == null) {
5584 // In this case we are either dropping the event, or have received
5585 // a move or up without a down. It is common to receive move
5586 // events in such a way, since this means the user is moving the
5587 // pointer without actually pressing down. All other cases should
5588 // be atypical, so let's log them.
Michael Chane96440f2009-05-06 10:27:36 -07005589 if (action != MotionEvent.ACTION_MOVE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005590 Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 }
Dianne Hackborn6adba242009-11-10 11:10:09 -08005592 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005593 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 if (qev != null) {
5596 mQueue.recycleEvent(qev);
5597 }
5598 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005599 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005600 }
5601 if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005602 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005603 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 if (qev != null) {
5606 mQueue.recycleEvent(qev);
5607 }
5608 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005609 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005610 }
Romain Guy06882f82009-06-10 13:36:04 -07005611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 WindowState target = (WindowState)targetObj;
Romain Guy06882f82009-06-10 13:36:04 -07005613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005614 final long eventTime = ev.getEventTime();
Michael Chan53071d62009-05-13 17:29:48 -07005615 final long eventTimeNano = ev.getEventTimeNano();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005616
Joe Onorato8a9b2202010-02-26 18:56:32 -08005617 //Slog.i(TAG, "Sending " + ev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618
5619 if (uid != 0 && uid != target.mSession.mUid) {
5620 if (mContext.checkPermission(
5621 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5622 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005623 Slog.w(TAG, "Permission denied: injecting pointer event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 + pid + " uid " + uid + " to window " + target
5625 + " owned by uid " + target.mSession.mUid);
5626 if (qev != null) {
5627 mQueue.recycleEvent(qev);
5628 }
5629 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005630 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 }
5632 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005633
Michael Chan53071d62009-05-13 17:29:48 -07005634 if (MEASURE_LATENCY) {
5635 lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5636 }
5637
Romain Guy06882f82009-06-10 13:36:04 -07005638 if ((target.mAttrs.flags &
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
5640 //target wants to ignore fat touch events
5641 boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
5642 //explicit flag to return without processing event further
5643 boolean returnFlag = false;
5644 if((action == MotionEvent.ACTION_DOWN)) {
5645 mFatTouch = false;
5646 if(cheekPress) {
5647 mFatTouch = true;
5648 returnFlag = true;
5649 }
5650 } else {
5651 if(action == MotionEvent.ACTION_UP) {
5652 if(mFatTouch) {
5653 //earlier even was invalid doesnt matter if current up is cheekpress or not
5654 mFatTouch = false;
5655 returnFlag = true;
5656 } else if(cheekPress) {
5657 //cancel the earlier event
5658 ev.setAction(MotionEvent.ACTION_CANCEL);
5659 action = MotionEvent.ACTION_CANCEL;
5660 }
5661 } else if(action == MotionEvent.ACTION_MOVE) {
5662 if(mFatTouch) {
5663 //two cases here
5664 //an invalid down followed by 0 or moves(valid or invalid)
Romain Guy06882f82009-06-10 13:36:04 -07005665 //a valid down, invalid move, more moves. want to ignore till up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 returnFlag = true;
5667 } else if(cheekPress) {
5668 //valid down followed by invalid moves
5669 //an invalid move have to cancel earlier action
5670 ev.setAction(MotionEvent.ACTION_CANCEL);
5671 action = MotionEvent.ACTION_CANCEL;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 //note that the subsequent invalid moves will not get here
5674 mFatTouch = true;
5675 }
5676 }
5677 } //else if action
5678 if(returnFlag) {
5679 //recycle que, ev
5680 if (qev != null) {
5681 mQueue.recycleEvent(qev);
5682 }
5683 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005684 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 }
5686 } //end if target
Michael Chane96440f2009-05-06 10:27:36 -07005687
Michael Chan9f028e62009-08-04 17:37:46 -07005688 // Enable this for testing the "right" value
5689 if (false && action == MotionEvent.ACTION_DOWN) {
Michael Chane96440f2009-05-06 10:27:36 -07005690 int max_events_per_sec = 35;
5691 try {
5692 max_events_per_sec = Integer.parseInt(SystemProperties
5693 .get("windowsmgr.max_events_per_sec"));
5694 if (max_events_per_sec < 1) {
5695 max_events_per_sec = 35;
5696 }
5697 } catch (NumberFormatException e) {
5698 }
5699 mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
5700 }
5701
5702 /*
5703 * Throttle events to minimize CPU usage when there's a flood of events
5704 * e.g. constant contact with the screen
5705 */
5706 if (action == MotionEvent.ACTION_MOVE) {
5707 long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
5708 long now = SystemClock.uptimeMillis();
5709 if (now < nextEventTime) {
5710 try {
5711 Thread.sleep(nextEventTime - now);
5712 } catch (InterruptedException e) {
5713 }
5714 mLastTouchEventTime = nextEventTime;
5715 } else {
5716 mLastTouchEventTime = now;
5717 }
5718 }
5719
Michael Chan53071d62009-05-13 17:29:48 -07005720 if (MEASURE_LATENCY) {
5721 lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano);
5722 }
5723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 synchronized(mWindowMap) {
Dianne Hackborn6adba242009-11-10 11:10:09 -08005725 if (!target.isVisibleLw()) {
5726 // During this motion dispatch, the target window has become
5727 // invisible.
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005728 dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
Dianne Hackborn6adba242009-11-10 11:10:09 -08005729 if (qev != null) {
5730 mQueue.recycleEvent(qev);
5731 }
5732 ev.recycle();
5733 return INJECT_SUCCEEDED;
5734 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 if (qev != null && action == MotionEvent.ACTION_MOVE) {
5737 mKeyWaiter.bindTargetWindowLocked(target,
5738 KeyWaiter.RETURN_PENDING_POINTER, qev);
5739 ev = null;
5740 } else {
5741 if (action == MotionEvent.ACTION_DOWN) {
5742 WindowState out = mKeyWaiter.mOutsideTouchTargets;
5743 if (out != null) {
5744 MotionEvent oev = MotionEvent.obtain(ev);
Adam Powell47482962010-05-27 15:19:58 -07005745 try {
5746 oev.setAction(MotionEvent.ACTION_OUTSIDE);
5747 do {
5748 final Rect frame = out.mFrame;
5749 oev.offsetLocation(-(float)frame.left, -(float)frame.top);
5750 try {
5751 out.mClient.dispatchPointer(oev, eventTime, false);
5752 } catch (android.os.RemoteException e) {
5753 Slog.i(TAG,
5754 "WINDOW DIED during outside motion dispatch: " + out);
5755 }
5756 oev.offsetLocation((float)frame.left, (float)frame.top);
5757 out = out.mNextOutsideTouch;
5758 } while (out != null);
5759 mKeyWaiter.mOutsideTouchTargets = null;
5760 } finally {
5761 oev.recycle();
5762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 }
5764 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005765
Dianne Hackborn90d2db32010-02-11 22:19:06 -08005766 dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005767
Dianne Hackborn6adba242009-11-10 11:10:09 -08005768 final Rect frame = target.mFrame;
5769 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
5770 mKeyWaiter.bindTargetWindowLocked(target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005771 }
5772 }
Romain Guy06882f82009-06-10 13:36:04 -07005773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 // finally offset the event to the target's coordinate system and
5775 // dispatch the event.
5776 try {
5777 if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005778 Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005780
Michael Chan53071d62009-05-13 17:29:48 -07005781 if (MEASURE_LATENCY) {
5782 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
5783 }
5784
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005785 target.mClient.dispatchPointer(ev, eventTime, true);
Michael Chan53071d62009-05-13 17:29:48 -07005786
5787 if (MEASURE_LATENCY) {
5788 lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
5789 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005790 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005792 Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 mKeyWaiter.mMotionTarget = null;
5794 try {
5795 removeWindow(target.mSession, target.mClient);
5796 } catch (java.util.NoSuchElementException ex) {
5797 // This will happen if the window has already been
5798 // removed.
5799 }
5800 }
Dianne Hackborncfaef692009-06-15 14:24:44 -07005801 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 }
Romain Guy06882f82009-06-10 13:36:04 -07005803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 /**
5805 * @return Returns true if event was dispatched, false if it was dropped for any reason
5806 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005807 private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005808 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
Romain Guy06882f82009-06-10 13:36:04 -07005810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811 Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005812 ev, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005813 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005814 Slog.w(TAG, "No focus window, dropping trackball: " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 if (qev != null) {
5816 mQueue.recycleEvent(qev);
5817 }
5818 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005819 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005820 }
5821 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
5822 if (qev != null) {
5823 mQueue.recycleEvent(qev);
5824 }
5825 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005826 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 }
Romain Guy06882f82009-06-10 13:36:04 -07005828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 if (uid != 0 && uid != focus.mSession.mUid) {
5832 if (mContext.checkPermission(
5833 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5834 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005835 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005836 + pid + " uid " + uid + " to window " + focus
5837 + " owned by uid " + focus.mSession.mUid);
5838 if (qev != null) {
5839 mQueue.recycleEvent(qev);
5840 }
5841 ev.recycle();
Dianne Hackborncfaef692009-06-15 14:24:44 -07005842 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005843 }
5844 }
Romain Guy06882f82009-06-10 13:36:04 -07005845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005846 final long eventTime = ev.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07005847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 synchronized(mWindowMap) {
5849 if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
5850 mKeyWaiter.bindTargetWindowLocked(focus,
5851 KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
5852 // We don't deliver movement events to the client, we hold
5853 // them and wait for them to call back.
5854 ev = null;
5855 } else {
5856 mKeyWaiter.bindTargetWindowLocked(focus);
5857 }
5858 }
Romain Guy06882f82009-06-10 13:36:04 -07005859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 try {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07005861 focus.mClient.dispatchTrackball(ev, eventTime, true);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005862 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005864 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 try {
5866 removeWindow(focus.mSession, focus.mClient);
5867 } catch (java.util.NoSuchElementException ex) {
5868 // This will happen if the window has already been
5869 // removed.
5870 }
5871 }
Romain Guy06882f82009-06-10 13:36:04 -07005872
Dianne Hackborncfaef692009-06-15 14:24:44 -07005873 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005874 }
Romain Guy06882f82009-06-10 13:36:04 -07005875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876 /**
5877 * @return Returns true if event was dispatched, false if it was dropped for any reason
5878 */
Dianne Hackborncfaef692009-06-15 14:24:44 -07005879 private int dispatchKey(KeyEvent event, int pid, int uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005880 if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005881
5882 Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005883 null, false, false, pid, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 if (focusObj == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005885 Slog.w(TAG, "No focus window, dropping: " + event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005886 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887 }
5888 if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005889 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005890 }
Romain Guy06882f82009-06-10 13:36:04 -07005891
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07005892 // Okay we have finished waiting for the last event to be processed.
5893 // First off, if this is a repeat event, check to see if there is
5894 // a corresponding up event in the queue. If there is, we will
5895 // just drop the repeat, because it makes no sense to repeat after
5896 // the user has released a key. (This is especially important for
5897 // long presses.)
5898 if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
5899 return INJECT_SUCCEEDED;
5900 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 WindowState focus = (WindowState)focusObj;
Romain Guy06882f82009-06-10 13:36:04 -07005903
Joe Onorato8a9b2202010-02-26 18:56:32 -08005904 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 TAG, "Dispatching to " + focus + ": " + event);
5906
5907 if (uid != 0 && uid != focus.mSession.mUid) {
5908 if (mContext.checkPermission(
5909 android.Manifest.permission.INJECT_EVENTS, pid, uid)
5910 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005911 Slog.w(TAG, "Permission denied: injecting key event from pid "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 + pid + " uid " + uid + " to window " + focus
5913 + " owned by uid " + focus.mSession.mUid);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005914 return INJECT_NO_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 }
5916 }
Romain Guy06882f82009-06-10 13:36:04 -07005917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 synchronized(mWindowMap) {
5919 mKeyWaiter.bindTargetWindowLocked(focus);
5920 }
5921
5922 // NOSHIP extra state logging
5923 mKeyWaiter.recordDispatchState(event, focus);
5924 // END NOSHIP
Romain Guy06882f82009-06-10 13:36:04 -07005925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005926 try {
5927 if (DEBUG_INPUT || DEBUG_FOCUS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005928 Slog.v(TAG, "Delivering key " + event.getKeyCode()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 + " to " + focus);
5930 }
5931 focus.mClient.dispatchKey(event);
Dianne Hackborncfaef692009-06-15 14:24:44 -07005932 return INJECT_SUCCEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 } catch (android.os.RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005934 Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005935 try {
5936 removeWindow(focus.mSession, focus.mClient);
5937 } catch (java.util.NoSuchElementException ex) {
5938 // This will happen if the window has already been
5939 // removed.
5940 }
5941 }
Romain Guy06882f82009-06-10 13:36:04 -07005942
Dianne Hackborncfaef692009-06-15 14:24:44 -07005943 return INJECT_FAILED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 }
Romain Guy06882f82009-06-10 13:36:04 -07005945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 public void pauseKeyDispatching(IBinder _token) {
5947 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5948 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005949 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 }
5951
5952 synchronized (mWindowMap) {
5953 WindowToken token = mTokenMap.get(_token);
5954 if (token != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005955 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5956 mInputMonitor.pauseDispatchingLw(token);
5957 } else {
5958 mKeyWaiter.pauseDispatchingLocked(token);
5959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 }
5961 }
5962 }
5963
5964 public void resumeKeyDispatching(IBinder _token) {
5965 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5966 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005967 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005968 }
5969
5970 synchronized (mWindowMap) {
5971 WindowToken token = mTokenMap.get(_token);
5972 if (token != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005973 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5974 mInputMonitor.resumeDispatchingLw(token);
5975 } else {
5976 mKeyWaiter.resumeDispatchingLocked(token);
5977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 }
5979 }
5980 }
5981
5982 public void setEventDispatching(boolean enabled) {
5983 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5984 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005985 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005986 }
5987
5988 synchronized (mWindowMap) {
Jeff Brown349703e2010-06-22 01:27:15 -07005989 if (ENABLE_NATIVE_INPUT_DISPATCH) {
5990 mInputMonitor.setEventDispatchingLw(enabled);
5991 } else {
5992 mKeyWaiter.setEventDispatchingLocked(enabled);
5993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 }
5995 }
Romain Guy06882f82009-06-10 13:36:04 -07005996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 /**
5998 * Injects a keystroke event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07005999 *
6000 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006001 * {@link SystemClock#uptimeMillis()} as the timebase.)
6002 * @param sync If true, wait for the event to be completed before returning to the caller.
6003 * @return Returns true if event was dispatched, false if it was dropped for any reason
6004 */
6005 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6006 long downTime = ev.getDownTime();
6007 long eventTime = ev.getEventTime();
6008
6009 int action = ev.getAction();
6010 int code = ev.getKeyCode();
6011 int repeatCount = ev.getRepeatCount();
6012 int metaState = ev.getMetaState();
6013 int deviceId = ev.getDeviceId();
6014 int scancode = ev.getScanCode();
6015
6016 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6017 if (downTime == 0) downTime = eventTime;
6018
6019 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
The Android Open Source Project10592532009-03-18 17:39:46 -07006020 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006021
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006022 final int pid = Binder.getCallingPid();
6023 final int uid = Binder.getCallingUid();
6024 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006025
6026 final int result;
6027 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006028 result = mInputManager.injectKeyEvent(newEvent, InputQueue.INPUT_EVENT_NATURE_KEY,
6029 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006030 } else {
6031 result = dispatchKey(newEvent, pid, uid);
6032 if (sync) {
6033 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006036
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006037 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006038 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 }
6040
6041 /**
6042 * Inject a pointer (touch) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07006043 *
6044 * @param ev A motion event describing the pointer (touch) action. (As noted in
6045 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 * {@link SystemClock#uptimeMillis()} as the timebase.)
6047 * @param sync If true, wait for the event to be completed before returning to the caller.
6048 * @return Returns true if event was dispatched, false if it was dropped for any reason
6049 */
6050 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006051 final int pid = Binder.getCallingPid();
6052 final int uid = Binder.getCallingUid();
6053 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006054
6055 final int result;
6056 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006057 result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TOUCH,
6058 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006059 } else {
6060 result = dispatchPointer(null, ev, pid, uid);
6061 if (sync) {
6062 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006065
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006066 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006067 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 }
Romain Guy06882f82009-06-10 13:36:04 -07006069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 /**
6071 * Inject a trackball (navigation device) event into the UI.
Romain Guy06882f82009-06-10 13:36:04 -07006072 *
6073 * @param ev A motion event describing the trackball action. (As noted in
6074 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006075 * {@link SystemClock#uptimeMillis()} as the timebase.)
6076 * @param sync If true, wait for the event to be completed before returning to the caller.
6077 * @return Returns true if event was dispatched, false if it was dropped for any reason
6078 */
6079 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006080 final int pid = Binder.getCallingPid();
6081 final int uid = Binder.getCallingUid();
6082 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006083
6084 final int result;
6085 if (ENABLE_NATIVE_INPUT_DISPATCH) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07006086 result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TRACKBALL,
6087 pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006088 } else {
6089 result = dispatchTrackball(null, ev, pid, uid);
6090 if (sync) {
6091 mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
6092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006093 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006094
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006095 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006096 return reportInjectionResult(result);
6097 }
6098
6099 private boolean reportInjectionResult(int result) {
6100 if (ENABLE_NATIVE_INPUT_DISPATCH) {
6101 switch (result) {
6102 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6103 Slog.w(TAG, "Input event injection permission denied.");
6104 throw new SecurityException(
6105 "Injecting to another application requires INJECT_EVENTS permission");
6106 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
6107 Slog.v(TAG, "Input event injection succeeded.");
6108 return true;
6109 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6110 Slog.w(TAG, "Input event injection timed out.");
6111 return false;
6112 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6113 default:
6114 Slog.w(TAG, "Input event injection failed.");
6115 return false;
6116 }
6117 } else {
6118 switch (result) {
6119 case INJECT_NO_PERMISSION:
6120 throw new SecurityException(
6121 "Injecting to another application requires INJECT_EVENTS permission");
6122 case INJECT_SUCCEEDED:
6123 return true;
6124 }
6125 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006127 }
Romain Guy06882f82009-06-10 13:36:04 -07006128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 private WindowState getFocusedWindow() {
6130 synchronized (mWindowMap) {
6131 return getFocusedWindowLocked();
6132 }
6133 }
6134
6135 private WindowState getFocusedWindowLocked() {
6136 return mCurrentFocus;
6137 }
Romain Guy06882f82009-06-10 13:36:04 -07006138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139 /**
6140 * This class holds the state for dispatching key events. This state
6141 * is protected by the KeyWaiter instance, NOT by the window lock. You
6142 * can be holding the main window lock while acquire the KeyWaiter lock,
6143 * but not the other way around.
6144 */
6145 final class KeyWaiter {
6146 // NOSHIP debugging
6147 public class DispatchState {
6148 private KeyEvent event;
6149 private WindowState focus;
6150 private long time;
6151 private WindowState lastWin;
6152 private IBinder lastBinder;
6153 private boolean finished;
6154 private boolean gotFirstWindow;
6155 private boolean eventDispatching;
6156 private long timeToSwitch;
6157 private boolean wasFrozen;
6158 private boolean focusPaused;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006159 private WindowState curFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006161 DispatchState(KeyEvent theEvent, WindowState theFocus) {
6162 focus = theFocus;
6163 event = theEvent;
6164 time = System.currentTimeMillis();
6165 // snapshot KeyWaiter state
6166 lastWin = mLastWin;
6167 lastBinder = mLastBinder;
6168 finished = mFinished;
6169 gotFirstWindow = mGotFirstWindow;
6170 eventDispatching = mEventDispatching;
6171 timeToSwitch = mTimeToSwitch;
6172 wasFrozen = mWasFrozen;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006173 curFocus = mCurrentFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006174 // cache the paused state at ctor time as well
6175 if (theFocus == null || theFocus.mToken == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006176 focusPaused = false;
6177 } else {
6178 focusPaused = theFocus.mToken.paused;
6179 }
6180 }
Romain Guy06882f82009-06-10 13:36:04 -07006181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006182 public String toString() {
6183 return "{{" + event + " to " + focus + " @ " + time
6184 + " lw=" + lastWin + " lb=" + lastBinder
6185 + " fin=" + finished + " gfw=" + gotFirstWindow
6186 + " ed=" + eventDispatching + " tts=" + timeToSwitch
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006187 + " wf=" + wasFrozen + " fp=" + focusPaused
Christopher Tate46d45252010-02-09 15:48:57 -08006188 + " mcf=" + curFocus + "}}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006189 }
6190 };
6191 private DispatchState mDispatchState = null;
6192 public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
6193 mDispatchState = new DispatchState(theEvent, theFocus);
6194 }
6195 // END NOSHIP
6196
6197 public static final int RETURN_NOTHING = 0;
6198 public static final int RETURN_PENDING_POINTER = 1;
6199 public static final int RETURN_PENDING_TRACKBALL = 2;
Romain Guy06882f82009-06-10 13:36:04 -07006200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006201 final Object SKIP_TARGET_TOKEN = new Object();
6202 final Object CONSUMED_EVENT_TOKEN = new Object();
Romain Guy06882f82009-06-10 13:36:04 -07006203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006204 private WindowState mLastWin = null;
6205 private IBinder mLastBinder = null;
6206 private boolean mFinished = true;
6207 private boolean mGotFirstWindow = false;
6208 private boolean mEventDispatching = true;
6209 private long mTimeToSwitch = 0;
6210 /* package */ boolean mWasFrozen = false;
Romain Guy06882f82009-06-10 13:36:04 -07006211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 // Target of Motion events
6213 WindowState mMotionTarget;
Romain Guy06882f82009-06-10 13:36:04 -07006214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006215 // Windows above the target who would like to receive an "outside"
6216 // touch event for any down events outside of them.
6217 WindowState mOutsideTouchTargets;
6218
6219 /**
6220 * Wait for the last event dispatch to complete, then find the next
6221 * target that should receive the given event and wait for that one
6222 * to be ready to receive it.
6223 */
6224 Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
6225 MotionEvent nextMotion, boolean isPointerEvent,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006226 boolean failIfTimeout, int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006227 long startTime = SystemClock.uptimeMillis();
6228 long keyDispatchingTimeout = 5 * 1000;
6229 long waitedFor = 0;
6230
6231 while (true) {
6232 // Figure out which window we care about. It is either the
6233 // last window we are waiting to have process the event or,
6234 // if none, then the next window we think the event should go
6235 // to. Note: we retrieve mLastWin outside of the lock, so
6236 // it may change before we lock. Thus we must check it again.
6237 WindowState targetWin = mLastWin;
6238 boolean targetIsNew = targetWin == null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006239 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 TAG, "waitForLastKey: mFinished=" + mFinished +
6241 ", mLastWin=" + mLastWin);
6242 if (targetIsNew) {
6243 Object target = findTargetWindow(nextKey, qev, nextMotion,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006244 isPointerEvent, callingPid, callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006245 if (target == SKIP_TARGET_TOKEN) {
6246 // The user has pressed a special key, and we are
6247 // dropping all pending events before it.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006248 if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 + " " + nextMotion);
6250 return null;
6251 }
6252 if (target == CONSUMED_EVENT_TOKEN) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006253 if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006254 + " " + nextMotion);
6255 return target;
6256 }
6257 targetWin = (WindowState)target;
6258 }
Romain Guy06882f82009-06-10 13:36:04 -07006259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 AppWindowToken targetApp = null;
Romain Guy06882f82009-06-10 13:36:04 -07006261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006262 // Now: is it okay to send the next event to this window?
6263 synchronized (this) {
6264 // First: did we come here based on the last window not
6265 // being null, but it changed by the time we got here?
6266 // If so, try again.
6267 if (!targetIsNew && mLastWin == null) {
6268 continue;
6269 }
Romain Guy06882f82009-06-10 13:36:04 -07006270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 // We never dispatch events if not finished with the
6272 // last one, or the display is frozen.
6273 if (mFinished && !mDisplayFrozen) {
6274 // If event dispatching is disabled, then we
6275 // just consume the events.
6276 if (!mEventDispatching) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006277 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 "Skipping event; dispatching disabled: "
6279 + nextKey + " " + nextMotion);
6280 return null;
6281 }
6282 if (targetWin != null) {
6283 // If this is a new target, and that target is not
6284 // paused or unresponsive, then all looks good to
6285 // handle the event.
6286 if (targetIsNew && !targetWin.mToken.paused) {
6287 return targetWin;
6288 }
Romain Guy06882f82009-06-10 13:36:04 -07006289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 // If we didn't find a target window, and there is no
6291 // focused app window, then just eat the events.
6292 } else if (mFocusedApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006293 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 "Skipping event; no focused app: "
6295 + nextKey + " " + nextMotion);
6296 return null;
6297 }
6298 }
Romain Guy06882f82009-06-10 13:36:04 -07006299
Joe Onorato8a9b2202010-02-26 18:56:32 -08006300 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 TAG, "Waiting for last key in " + mLastBinder
6302 + " target=" + targetWin
6303 + " mFinished=" + mFinished
6304 + " mDisplayFrozen=" + mDisplayFrozen
6305 + " targetIsNew=" + targetIsNew
6306 + " paused="
6307 + (targetWin != null ? targetWin.mToken.paused : false)
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006308 + " mFocusedApp=" + mFocusedApp
6309 + " mCurrentFocus=" + mCurrentFocus);
Romain Guy06882f82009-06-10 13:36:04 -07006310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006311 targetApp = targetWin != null
6312 ? targetWin.mAppToken : mFocusedApp;
Romain Guy06882f82009-06-10 13:36:04 -07006313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 long curTimeout = keyDispatchingTimeout;
6315 if (mTimeToSwitch != 0) {
6316 long now = SystemClock.uptimeMillis();
6317 if (mTimeToSwitch <= now) {
6318 // If an app switch key has been pressed, and we have
6319 // waited too long for the current app to finish
6320 // processing keys, then wait no more!
Christopher Tate136b1f92010-02-11 17:51:24 -08006321 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 continue;
6323 }
6324 long switchTimeout = mTimeToSwitch - now;
6325 if (curTimeout > switchTimeout) {
6326 curTimeout = switchTimeout;
6327 }
6328 }
Romain Guy06882f82009-06-10 13:36:04 -07006329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 try {
6331 // after that continue
6332 // processing keys, so we don't get stuck.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006333 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006334 TAG, "Waiting for key dispatch: " + curTimeout);
6335 wait(curTimeout);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006336 if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 + SystemClock.uptimeMillis() + " startTime="
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006338 + startTime + " switchTime=" + mTimeToSwitch
6339 + " target=" + targetWin + " mLW=" + mLastWin
6340 + " mLB=" + mLastBinder + " fin=" + mFinished
6341 + " mCurrentFocus=" + mCurrentFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 } catch (InterruptedException e) {
6343 }
6344 }
6345
6346 // If we were frozen during configuration change, restart the
6347 // timeout checks from now; otherwise look at whether we timed
6348 // out before awakening.
6349 if (mWasFrozen) {
6350 waitedFor = 0;
6351 mWasFrozen = false;
6352 } else {
6353 waitedFor = SystemClock.uptimeMillis() - startTime;
6354 }
6355
6356 if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
6357 IApplicationToken at = null;
6358 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006359 Slog.w(TAG, "Key dispatching timed out sending to " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006360 (targetWin != null ? targetWin.mAttrs.getTitle()
Ken Shirriff8200b202010-02-04 13:34:37 -08006361 : "<null>: no window ready for key dispatch"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 // NOSHIP debugging
Joe Onorato8a9b2202010-02-26 18:56:32 -08006363 Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
6364 Slog.w(TAG, "Current dispatch state: " +
Ken Shirriff8200b202010-02-04 13:34:37 -08006365 new DispatchState(nextKey, targetWin));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006366 // END NOSHIP
6367 //dump();
6368 if (targetWin != null) {
6369 at = targetWin.getAppToken();
6370 } else if (targetApp != null) {
6371 at = targetApp.appToken;
6372 }
6373 }
6374
6375 boolean abort = true;
6376 if (at != null) {
6377 try {
6378 long timeout = at.getKeyDispatchingTimeout();
6379 if (timeout > waitedFor) {
6380 // we did not wait the proper amount of time for this application.
6381 // set the timeout to be the real timeout and wait again.
6382 keyDispatchingTimeout = timeout - waitedFor;
6383 continue;
6384 } else {
6385 abort = at.keyDispatchingTimedOut();
6386 }
6387 } catch (RemoteException ex) {
6388 }
6389 }
6390
6391 synchronized (this) {
6392 if (abort && (mLastWin == targetWin || targetWin == null)) {
6393 mFinished = true;
Romain Guy06882f82009-06-10 13:36:04 -07006394 if (mLastWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006395 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 "Window " + mLastWin +
6397 " timed out on key input");
6398 if (mLastWin.mToken.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006399 Slog.w(TAG, "Un-pausing dispatching to this window");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006400 mLastWin.mToken.paused = false;
6401 }
6402 }
6403 if (mMotionTarget == targetWin) {
6404 mMotionTarget = null;
6405 }
6406 mLastWin = null;
6407 mLastBinder = null;
6408 if (failIfTimeout || targetWin == null) {
6409 return null;
6410 }
6411 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006412 Slog.w(TAG, "Continuing to wait for key to be dispatched");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 startTime = SystemClock.uptimeMillis();
6414 }
6415 }
6416 }
6417 }
6418 }
Romain Guy06882f82009-06-10 13:36:04 -07006419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006421 MotionEvent nextMotion, boolean isPointerEvent,
6422 int callingPid, int callingUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006423 mOutsideTouchTargets = null;
Romain Guy06882f82009-06-10 13:36:04 -07006424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 if (nextKey != null) {
6426 // Find the target window for a normal key event.
6427 final int keycode = nextKey.getKeyCode();
6428 final int repeatCount = nextKey.getRepeatCount();
6429 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
6430 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 if (!dispatch) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006433 if (callingUid == 0 ||
6434 mContext.checkPermission(
6435 android.Manifest.permission.INJECT_EVENTS,
6436 callingPid, callingUid)
6437 == PackageManager.PERMISSION_GRANTED) {
6438 mPolicy.interceptKeyTi(null, keycode,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006439 nextKey.getMetaState(), down, repeatCount,
6440 nextKey.getFlags());
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006441 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006442 Slog.w(TAG, "Event timeout during app switch: dropping "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 + nextKey);
6444 return SKIP_TARGET_TOKEN;
6445 }
Romain Guy06882f82009-06-10 13:36:04 -07006446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
Romain Guy06882f82009-06-10 13:36:04 -07006448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 WindowState focus = null;
6450 synchronized(mWindowMap) {
6451 focus = getFocusedWindowLocked();
6452 }
Romain Guy06882f82009-06-10 13:36:04 -07006453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
Romain Guy06882f82009-06-10 13:36:04 -07006455
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006456 if (callingUid == 0 ||
6457 (focus != null && callingUid == focus.mSession.mUid) ||
6458 mContext.checkPermission(
6459 android.Manifest.permission.INJECT_EVENTS,
6460 callingPid, callingUid)
6461 == PackageManager.PERMISSION_GRANTED) {
6462 if (mPolicy.interceptKeyTi(focus,
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006463 keycode, nextKey.getMetaState(), down, repeatCount,
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006464 nextKey.getFlags())) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006465 return CONSUMED_EVENT_TOKEN;
6466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 }
Romain Guy06882f82009-06-10 13:36:04 -07006468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006469 return focus;
Romain Guy06882f82009-06-10 13:36:04 -07006470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006471 } else if (!isPointerEvent) {
6472 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
6473 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006474 Slog.w(TAG, "Event timeout during app switch: dropping trackball "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006475 + nextMotion);
6476 return SKIP_TARGET_TOKEN;
6477 }
Romain Guy06882f82009-06-10 13:36:04 -07006478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 WindowState focus = null;
6480 synchronized(mWindowMap) {
6481 focus = getFocusedWindowLocked();
6482 }
Romain Guy06882f82009-06-10 13:36:04 -07006483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
6485 return focus;
6486 }
Romain Guy06882f82009-06-10 13:36:04 -07006487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 if (nextMotion == null) {
6489 return SKIP_TARGET_TOKEN;
6490 }
Romain Guy06882f82009-06-10 13:36:04 -07006491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006492 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
6493 KeyEvent.KEYCODE_UNKNOWN);
6494 if (!dispatch) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006495 Slog.w(TAG, "Event timeout during app switch: dropping pointer "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006496 + nextMotion);
6497 return SKIP_TARGET_TOKEN;
6498 }
Romain Guy06882f82009-06-10 13:36:04 -07006499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 // Find the target window for a pointer event.
6501 int action = nextMotion.getAction();
6502 final float xf = nextMotion.getX();
6503 final float yf = nextMotion.getY();
6504 final long eventTime = nextMotion.getEventTime();
Romain Guy06882f82009-06-10 13:36:04 -07006505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 final boolean screenWasOff = qev != null
6507 && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07006508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 WindowState target = null;
Romain Guy06882f82009-06-10 13:36:04 -07006510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511 synchronized(mWindowMap) {
6512 synchronized (this) {
6513 if (action == MotionEvent.ACTION_DOWN) {
6514 if (mMotionTarget != null) {
6515 // this is weird, we got a pen down, but we thought it was
6516 // already down!
6517 // XXX: We should probably send an ACTION_UP to the current
6518 // target.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006519 Slog.w(TAG, "Pointer down received while already down in: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006520 + mMotionTarget);
6521 mMotionTarget = null;
6522 }
Romain Guy06882f82009-06-10 13:36:04 -07006523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006524 // ACTION_DOWN is special, because we need to lock next events to
6525 // the window we'll land onto.
6526 final int x = (int)xf;
6527 final int y = (int)yf;
Romain Guy06882f82009-06-10 13:36:04 -07006528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 final ArrayList windows = mWindows;
6530 final int N = windows.size();
6531 WindowState topErrWindow = null;
6532 final Rect tmpRect = mTempRect;
6533 for (int i=N-1; i>=0; i--) {
6534 WindowState child = (WindowState)windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006535 //Slog.i(TAG, "Checking dispatch to: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 final int flags = child.mAttrs.flags;
6537 if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
6538 if (topErrWindow == null) {
6539 topErrWindow = child;
6540 }
6541 }
6542 if (!child.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006543 //Slog.i(TAG, "Not visible!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 continue;
6545 }
6546 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006547 //Slog.i(TAG, "Not touchable!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006548 if ((flags & WindowManager.LayoutParams
6549 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6550 child.mNextOutsideTouch = mOutsideTouchTargets;
6551 mOutsideTouchTargets = child;
6552 }
6553 continue;
6554 }
6555 tmpRect.set(child.mFrame);
6556 if (child.mTouchableInsets == ViewTreeObserver
6557 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
6558 // The touch is inside of the window if it is
6559 // inside the frame, AND the content part of that
6560 // frame that was given by the application.
6561 tmpRect.left += child.mGivenContentInsets.left;
6562 tmpRect.top += child.mGivenContentInsets.top;
6563 tmpRect.right -= child.mGivenContentInsets.right;
6564 tmpRect.bottom -= child.mGivenContentInsets.bottom;
6565 } else if (child.mTouchableInsets == ViewTreeObserver
6566 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
6567 // The touch is inside of the window if it is
6568 // inside the frame, AND the visible part of that
6569 // frame that was given by the application.
6570 tmpRect.left += child.mGivenVisibleInsets.left;
6571 tmpRect.top += child.mGivenVisibleInsets.top;
6572 tmpRect.right -= child.mGivenVisibleInsets.right;
6573 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
6574 }
6575 final int touchFlags = flags &
6576 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6577 |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
6578 if (tmpRect.contains(x, y) || touchFlags == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006579 //Slog.i(TAG, "Using this target!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 if (!screenWasOff || (flags &
6581 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
6582 mMotionTarget = child;
6583 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006584 //Slog.i(TAG, "Waking, skip!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006585 mMotionTarget = null;
6586 }
6587 break;
6588 }
Romain Guy06882f82009-06-10 13:36:04 -07006589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 if ((flags & WindowManager.LayoutParams
6591 .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
6592 child.mNextOutsideTouch = mOutsideTouchTargets;
6593 mOutsideTouchTargets = child;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006594 //Slog.i(TAG, "Adding to outside target list: " + child);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 }
6596 }
6597
6598 // if there's an error window but it's not accepting
6599 // focus (typically because it is not yet visible) just
6600 // wait for it -- any other focused window may in fact
6601 // be in ANR state.
6602 if (topErrWindow != null && mMotionTarget != topErrWindow) {
6603 mMotionTarget = null;
6604 }
6605 }
Romain Guy06882f82009-06-10 13:36:04 -07006606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 target = mMotionTarget;
6608 }
6609 }
Romain Guy06882f82009-06-10 13:36:04 -07006610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 wakeupIfNeeded(target, eventType(nextMotion));
Romain Guy06882f82009-06-10 13:36:04 -07006612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 // Pointer events are a little different -- if there isn't a
6614 // target found for any event, then just drop it.
6615 return target != null ? target : SKIP_TARGET_TOKEN;
6616 }
Romain Guy06882f82009-06-10 13:36:04 -07006617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 boolean checkShouldDispatchKey(int keycode) {
6619 synchronized (this) {
6620 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
6621 mTimeToSwitch = 0;
6622 return true;
6623 }
6624 if (mTimeToSwitch != 0
6625 && mTimeToSwitch < SystemClock.uptimeMillis()) {
6626 return false;
6627 }
6628 return true;
6629 }
6630 }
Romain Guy06882f82009-06-10 13:36:04 -07006631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 void bindTargetWindowLocked(WindowState win,
6633 int pendingWhat, QueuedEvent pendingMotion) {
6634 synchronized (this) {
6635 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
6636 }
6637 }
Romain Guy06882f82009-06-10 13:36:04 -07006638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006639 void bindTargetWindowLocked(WindowState win) {
6640 synchronized (this) {
6641 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
6642 }
6643 }
6644
6645 void bindTargetWindowLockedLocked(WindowState win,
6646 int pendingWhat, QueuedEvent pendingMotion) {
6647 mLastWin = win;
6648 mLastBinder = win.mClient.asBinder();
6649 mFinished = false;
6650 if (pendingMotion != null) {
6651 final Session s = win.mSession;
6652 if (pendingWhat == RETURN_PENDING_POINTER) {
6653 releasePendingPointerLocked(s);
6654 s.mPendingPointerMove = pendingMotion;
6655 s.mPendingPointerWindow = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006656 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 "bindTargetToWindow " + s.mPendingPointerMove);
6658 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
6659 releasePendingTrackballLocked(s);
6660 s.mPendingTrackballMove = pendingMotion;
6661 s.mPendingTrackballWindow = win;
6662 }
6663 }
6664 }
Romain Guy06882f82009-06-10 13:36:04 -07006665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006666 void releasePendingPointerLocked(Session s) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006667 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 "releasePendingPointer " + s.mPendingPointerMove);
6669 if (s.mPendingPointerMove != null) {
6670 mQueue.recycleEvent(s.mPendingPointerMove);
6671 s.mPendingPointerMove = null;
6672 }
6673 }
Romain Guy06882f82009-06-10 13:36:04 -07006674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 void releasePendingTrackballLocked(Session s) {
6676 if (s.mPendingTrackballMove != null) {
6677 mQueue.recycleEvent(s.mPendingTrackballMove);
6678 s.mPendingTrackballMove = null;
6679 }
6680 }
Romain Guy06882f82009-06-10 13:36:04 -07006681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 MotionEvent finishedKey(Session session, IWindow client, boolean force,
6683 int returnWhat) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006684 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 TAG, "finishedKey: client=" + client + ", force=" + force);
6686
6687 if (client == null) {
6688 return null;
6689 }
6690
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006691 MotionEvent res = null;
6692 QueuedEvent qev = null;
6693 WindowState win = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006696 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006697 TAG, "finishedKey: client=" + client.asBinder()
6698 + ", force=" + force + ", last=" + mLastBinder
6699 + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
6700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 if (returnWhat == RETURN_PENDING_POINTER) {
6702 qev = session.mPendingPointerMove;
6703 win = session.mPendingPointerWindow;
6704 session.mPendingPointerMove = null;
6705 session.mPendingPointerWindow = null;
6706 } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
6707 qev = session.mPendingTrackballMove;
6708 win = session.mPendingTrackballWindow;
6709 session.mPendingTrackballMove = null;
6710 session.mPendingTrackballWindow = null;
6711 }
Romain Guy06882f82009-06-10 13:36:04 -07006712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 if (mLastBinder == client.asBinder()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006714 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 TAG, "finishedKey: last paused="
6716 + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
6717 if (mLastWin != null && (!mLastWin.mToken.paused || force
6718 || !mEventDispatching)) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006719 doFinishedKeyLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 } else {
6721 // Make sure to wake up anyone currently waiting to
6722 // dispatch a key, so they can re-evaluate their
6723 // current situation.
6724 mFinished = true;
6725 notifyAll();
6726 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 }
Romain Guy06882f82009-06-10 13:36:04 -07006728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006729 if (qev != null) {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006730 res = (MotionEvent)qev.event;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006731 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 "Returning pending motion: " + res);
6733 mQueue.recycleEvent(qev);
6734 if (win != null && returnWhat == RETURN_PENDING_POINTER) {
6735 res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
6736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006737 }
Christopher Tate2624fbc2009-12-11 12:11:31 -08006738 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006739
Christopher Tate2624fbc2009-12-11 12:11:31 -08006740 if (res != null && returnWhat == RETURN_PENDING_POINTER) {
6741 synchronized (mWindowMap) {
Dianne Hackborn90d2db32010-02-11 22:19:06 -08006742 dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006743 }
6744 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006745
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07006746 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006747 }
6748
6749 void tickle() {
6750 synchronized (this) {
6751 notifyAll();
6752 }
6753 }
Romain Guy06882f82009-06-10 13:36:04 -07006754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 void handleNewWindowLocked(WindowState newWindow) {
6756 if (!newWindow.canReceiveKeys()) {
6757 return;
6758 }
6759 synchronized (this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006760 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 TAG, "New key dispatch window: win="
6762 + newWindow.mClient.asBinder()
6763 + ", last=" + mLastBinder
6764 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6765 + "), finished=" + mFinished + ", paused="
6766 + newWindow.mToken.paused);
6767
6768 // Displaying a window implicitly causes dispatching to
6769 // be unpaused. (This is to protect against bugs if someone
6770 // pauses dispatching but forgets to resume.)
6771 newWindow.mToken.paused = false;
6772
6773 mGotFirstWindow = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774
6775 if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006776 if (DEBUG_INPUT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 "New SYSTEM_ERROR window; resetting state");
6778 mLastWin = null;
6779 mLastBinder = null;
6780 mMotionTarget = null;
6781 mFinished = true;
6782 } else if (mLastWin != null) {
6783 // If the new window is above the window we are
6784 // waiting on, then stop waiting and let key dispatching
6785 // start on the new guy.
Joe Onorato8a9b2202010-02-26 18:56:32 -08006786 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006787 TAG, "Last win layer=" + mLastWin.mLayer
6788 + ", new win layer=" + newWindow.mLayer);
6789 if (newWindow.mLayer >= mLastWin.mLayer) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006790 // The new window is above the old; finish pending input to the last
6791 // window and start directing it to the new one.
6792 mLastWin.mToken.paused = false;
Christopher Tate136b1f92010-02-11 17:51:24 -08006793 doFinishedKeyLocked(false); // does a notifyAll()
6794 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 }
6796 }
6797
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08006798 // Now that we've put a new window state in place, make the event waiter
6799 // take notice and retarget its attentions.
6800 notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 }
6802 }
6803
6804 void pauseDispatchingLocked(WindowToken token) {
6805 synchronized (this)
6806 {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006807 if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 token.paused = true;
6809
6810 /*
6811 if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
6812 mPaused = true;
6813 } else {
6814 if (mLastWin == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006815 Slog.i(TAG, "Key dispatching not paused: no last window.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006816 } else if (mFinished) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006817 Slog.i(TAG, "Key dispatching not paused: finished last key.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006819 Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 }
6821 }
6822 */
6823 }
6824 }
6825
6826 void resumeDispatchingLocked(WindowToken token) {
6827 synchronized (this) {
6828 if (token.paused) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006829 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006830 TAG, "Resuming WindowToken " + token
6831 + ", last=" + mLastBinder
6832 + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
6833 + "), finished=" + mFinished + ", paused="
6834 + token.paused);
6835 token.paused = false;
6836 if (mLastWin != null && mLastWin.mToken == token && mFinished) {
Christopher Tate136b1f92010-02-11 17:51:24 -08006837 doFinishedKeyLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 } else {
6839 notifyAll();
6840 }
6841 }
6842 }
6843 }
6844
6845 void setEventDispatchingLocked(boolean enabled) {
6846 synchronized (this) {
6847 mEventDispatching = enabled;
6848 notifyAll();
6849 }
6850 }
Romain Guy06882f82009-06-10 13:36:04 -07006851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006852 void appSwitchComing() {
6853 synchronized (this) {
6854 // Don't wait for more than .5 seconds for app to finish
6855 // processing the pending events.
6856 long now = SystemClock.uptimeMillis() + 500;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006857 if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
6859 mTimeToSwitch = now;
6860 }
6861 notifyAll();
6862 }
6863 }
Romain Guy06882f82009-06-10 13:36:04 -07006864
Christopher Tate136b1f92010-02-11 17:51:24 -08006865 private final void doFinishedKeyLocked(boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 if (mLastWin != null) {
6867 releasePendingPointerLocked(mLastWin.mSession);
6868 releasePendingTrackballLocked(mLastWin.mSession);
6869 }
Romain Guy06882f82009-06-10 13:36:04 -07006870
Christopher Tate136b1f92010-02-11 17:51:24 -08006871 if (force || mLastWin == null || !mLastWin.mToken.paused
6872 || !mLastWin.isVisibleLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 // If the current window has been paused, we aren't -really-
6874 // finished... so let the waiters still wait.
6875 mLastWin = null;
6876 mLastBinder = null;
6877 }
6878 mFinished = true;
6879 notifyAll();
6880 }
6881 }
6882
6883 private class KeyQ extends KeyInputQueue
6884 implements KeyInputQueue.FilterCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 KeyQ() {
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07006886 super(mContext, WindowManagerService.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 }
6888
6889 @Override
6890 boolean preprocessEvent(InputDevice device, RawInputEvent event) {
6891 if (mPolicy.preprocessInputEventTq(event)) {
6892 return true;
6893 }
Romain Guy06882f82009-06-10 13:36:04 -07006894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 switch (event.type) {
6896 case RawInputEvent.EV_KEY: {
6897 // XXX begin hack
6898 if (DEBUG) {
6899 if (event.keycode == KeyEvent.KEYCODE_G) {
6900 if (event.value != 0) {
6901 // G down
6902 mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
6903 }
6904 return false;
6905 }
6906 if (event.keycode == KeyEvent.KEYCODE_D) {
6907 if (event.value != 0) {
6908 //dump();
6909 }
6910 return false;
6911 }
6912 }
6913 // XXX end hack
Romain Guy06882f82009-06-10 13:36:04 -07006914
Charles Mendis322591c2009-10-29 11:06:59 -07006915 boolean screenIsOff = !mPowerManager.isScreenOn();
6916 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006917 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
Romain Guy06882f82009-06-10 13:36:04 -07006918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006919 if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
6920 mPowerManager.goToSleep(event.when);
6921 }
6922
6923 if (screenIsOff) {
6924 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6925 }
6926 if (screenIsDim) {
6927 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6928 }
6929 if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
6930 mPowerManager.userActivity(event.when, false,
Michael Chane96440f2009-05-06 10:27:36 -07006931 LocalPowerManager.BUTTON_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 }
Romain Guy06882f82009-06-10 13:36:04 -07006933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006934 if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
6935 if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
6936 filterQueue(this);
6937 mKeyWaiter.appSwitchComing();
6938 }
6939 return true;
6940 } else {
6941 return false;
6942 }
6943 }
Romain Guy06882f82009-06-10 13:36:04 -07006944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 case RawInputEvent.EV_REL: {
Charles Mendis322591c2009-10-29 11:06:59 -07006946 boolean screenIsOff = !mPowerManager.isScreenOn();
6947 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 if (screenIsOff) {
6949 if (!mPolicy.isWakeRelMovementTq(event.deviceId,
6950 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006951 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 return false;
6953 }
6954 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6955 }
6956 if (screenIsDim) {
6957 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6958 }
6959 return true;
6960 }
Romain Guy06882f82009-06-10 13:36:04 -07006961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 case RawInputEvent.EV_ABS: {
Charles Mendis322591c2009-10-29 11:06:59 -07006963 boolean screenIsOff = !mPowerManager.isScreenOn();
6964 boolean screenIsDim = !mPowerManager.isScreenBright();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 if (screenIsOff) {
6966 if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
6967 device.classes, event)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006968 //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 return false;
6970 }
6971 event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
6972 }
6973 if (screenIsDim) {
6974 event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
6975 }
6976 return true;
6977 }
Romain Guy06882f82009-06-10 13:36:04 -07006978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 default:
6980 return true;
6981 }
6982 }
6983
6984 public int filterEvent(QueuedEvent ev) {
6985 switch (ev.classType) {
6986 case RawInputEvent.CLASS_KEYBOARD:
6987 KeyEvent ke = (KeyEvent)ev.event;
6988 if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006989 Slog.w(TAG, "Dropping movement key during app switch: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 + ke.getKeyCode() + ", action=" + ke.getAction());
6991 return FILTER_REMOVE;
6992 }
6993 return FILTER_ABORT;
6994 default:
6995 return FILTER_KEEP;
6996 }
6997 }
Michael Chan53071d62009-05-13 17:29:48 -07006998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006999
7000 public boolean detectSafeMode() {
7001 mSafeMode = mPolicy.detectSafeMode();
7002 return mSafeMode;
7003 }
Romain Guy06882f82009-06-10 13:36:04 -07007004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 public void systemReady() {
7006 mPolicy.systemReady();
7007 }
Romain Guy06882f82009-06-10 13:36:04 -07007008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 private final class InputDispatcherThread extends Thread {
7010 // Time to wait when there is nothing to do: 9999 seconds.
7011 static final int LONG_WAIT=9999*1000;
7012
7013 public InputDispatcherThread() {
7014 super("InputDispatcher");
7015 }
Romain Guy06882f82009-06-10 13:36:04 -07007016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007017 @Override
7018 public void run() {
7019 while (true) {
7020 try {
7021 process();
7022 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007023 Slog.e(TAG, "Exception in input dispatcher", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 }
7025 }
7026 }
Romain Guy06882f82009-06-10 13:36:04 -07007027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007028 private void process() {
7029 android.os.Process.setThreadPriority(
7030 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
Romain Guy06882f82009-06-10 13:36:04 -07007031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007032 // The last key event we saw
7033 KeyEvent lastKey = null;
7034
7035 // Last keydown time for auto-repeating keys
7036 long lastKeyTime = SystemClock.uptimeMillis();
7037 long nextKeyTime = lastKeyTime+LONG_WAIT;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007038 long downTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039
Romain Guy06882f82009-06-10 13:36:04 -07007040 // How many successive repeats we generated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 int keyRepeatCount = 0;
7042
7043 // Need to report that configuration has changed?
7044 boolean configChanged = false;
Romain Guy06882f82009-06-10 13:36:04 -07007045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007046 while (true) {
7047 long curTime = SystemClock.uptimeMillis();
7048
Joe Onorato8a9b2202010-02-26 18:56:32 -08007049 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 TAG, "Waiting for next key: now=" + curTime
7051 + ", repeat @ " + nextKeyTime);
7052
7053 // Retrieve next event, waiting only as long as the next
7054 // repeat timeout. If the configuration has changed, then
7055 // don't wait at all -- we'll report the change as soon as
7056 // we have processed all events.
7057 QueuedEvent ev = mQueue.getEvent(
7058 (int)((!configChanged && curTime < nextKeyTime)
7059 ? (nextKeyTime-curTime) : 0));
7060
Joe Onorato8a9b2202010-02-26 18:56:32 -08007061 if (DEBUG_INPUT && ev != null) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007062 TAG, "Event: type=" + ev.classType + " data=" + ev.event);
7063
Michael Chan53071d62009-05-13 17:29:48 -07007064 if (MEASURE_LATENCY) {
7065 lt.sample("2 got event ", System.nanoTime() - ev.whenNano);
7066 }
7067
Mike Lockwood3d0ea722009-10-21 22:58:29 -04007068 if (lastKey != null && !mPolicy.allowKeyRepeat()) {
7069 // cancel key repeat at the request of the policy.
7070 lastKey = null;
7071 downTime = 0;
7072 lastKeyTime = curTime;
7073 nextKeyTime = curTime + LONG_WAIT;
7074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 try {
7076 if (ev != null) {
Michael Chan53071d62009-05-13 17:29:48 -07007077 curTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007078 int eventType;
7079 if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
7080 eventType = eventType((MotionEvent)ev.event);
7081 } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
7082 ev.classType == RawInputEvent.CLASS_TRACKBALL) {
7083 eventType = LocalPowerManager.BUTTON_EVENT;
7084 } else {
7085 eventType = LocalPowerManager.OTHER_EVENT;
7086 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07007087 try {
Michael Chan53071d62009-05-13 17:29:48 -07007088 if ((curTime - mLastBatteryStatsCallTime)
Michael Chane96440f2009-05-06 10:27:36 -07007089 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
Michael Chan53071d62009-05-13 17:29:48 -07007090 mLastBatteryStatsCallTime = curTime;
Michael Chane96440f2009-05-06 10:27:36 -07007091 mBatteryStats.noteInputEvent();
7092 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07007093 } catch (RemoteException e) {
7094 // Ignore
7095 }
Michael Chane10de972009-05-18 11:24:50 -07007096
Mike Lockwood5db42402009-11-30 14:51:51 -05007097 if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
7098 // do not wake screen in this case
7099 } else if (eventType != TOUCH_EVENT
Michael Chane10de972009-05-18 11:24:50 -07007100 && eventType != LONG_TOUCH_EVENT
7101 && eventType != CHEEK_EVENT) {
7102 mPowerManager.userActivity(curTime, false,
7103 eventType, false);
7104 } else if (mLastTouchEventType != eventType
7105 || (curTime - mLastUserActivityCallTime)
7106 >= MIN_TIME_BETWEEN_USERACTIVITIES) {
7107 mLastUserActivityCallTime = curTime;
7108 mLastTouchEventType = eventType;
7109 mPowerManager.userActivity(curTime, false,
7110 eventType, false);
7111 }
7112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007113 switch (ev.classType) {
7114 case RawInputEvent.CLASS_KEYBOARD:
7115 KeyEvent ke = (KeyEvent)ev.event;
7116 if (ke.isDown()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007117 lastKeyTime = curTime;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007118 if (lastKey != null &&
7119 ke.getKeyCode() == lastKey.getKeyCode()) {
7120 keyRepeatCount++;
7121 // Arbitrary long timeout to block
7122 // repeating here since we know that
7123 // the device driver takes care of it.
7124 nextKeyTime = lastKeyTime + LONG_WAIT;
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07007125 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007126 TAG, "Received repeated key down");
7127 } else {
7128 downTime = curTime;
7129 keyRepeatCount = 0;
7130 nextKeyTime = lastKeyTime
7131 + ViewConfiguration.getLongPressTimeout();
The Android Open Source Project2a9ae012010-05-12 12:33:35 -07007132 if (DEBUG_INPUT) Slog.v(
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007133 TAG, "Received key down: first repeat @ "
7134 + nextKeyTime);
7135 }
7136 lastKey = ke;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 } else {
7138 lastKey = null;
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007139 downTime = 0;
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007140 keyRepeatCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 // Arbitrary long timeout.
7142 lastKeyTime = curTime;
7143 nextKeyTime = curTime + LONG_WAIT;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007144 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145 TAG, "Received key up: ignore repeat @ "
7146 + nextKeyTime);
7147 }
Kristian Dreher133bfdf2010-02-23 08:50:58 +01007148 if (keyRepeatCount > 0) {
7149 dispatchKey(KeyEvent.changeTimeRepeat(ke,
7150 ke.getEventTime(), keyRepeatCount), 0, 0);
7151 } else {
7152 dispatchKey(ke, 0, 0);
7153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007154 mQueue.recycleEvent(ev);
7155 break;
7156 case RawInputEvent.CLASS_TOUCHSCREEN:
Joe Onorato8a9b2202010-02-26 18:56:32 -08007157 //Slog.i(TAG, "Read next event " + ev);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
7159 break;
7160 case RawInputEvent.CLASS_TRACKBALL:
7161 dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
7162 break;
7163 case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
7164 configChanged = true;
7165 break;
7166 default:
7167 mQueue.recycleEvent(ev);
7168 break;
7169 }
Romain Guy06882f82009-06-10 13:36:04 -07007170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 } else if (configChanged) {
7172 configChanged = false;
7173 sendNewConfiguration();
Romain Guy06882f82009-06-10 13:36:04 -07007174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007175 } else if (lastKey != null) {
7176 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007178 // Timeout occurred while key was down. If it is at or
7179 // past the key repeat time, dispatch the repeat.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007180 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 TAG, "Key timeout: repeat=" + nextKeyTime
7182 + ", now=" + curTime);
7183 if (curTime < nextKeyTime) {
7184 continue;
7185 }
Romain Guy06882f82009-06-10 13:36:04 -07007186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 lastKeyTime = nextKeyTime;
7188 nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
7189 keyRepeatCount++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007190 if (DEBUG_INPUT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 TAG, "Key repeat: count=" + keyRepeatCount
7192 + ", next @ " + nextKeyTime);
Dianne Hackborn83fe3f52009-09-12 23:38:30 -07007193 KeyEvent newEvent;
7194 if (downTime != 0 && (downTime
7195 + ViewConfiguration.getLongPressTimeout())
7196 <= curTime) {
7197 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7198 curTime, keyRepeatCount,
7199 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
7200 downTime = 0;
7201 } else {
7202 newEvent = KeyEvent.changeTimeRepeat(lastKey,
7203 curTime, keyRepeatCount);
7204 }
7205 dispatchKey(newEvent, 0, 0);
Romain Guy06882f82009-06-10 13:36:04 -07007206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007207 } else {
7208 curTime = SystemClock.uptimeMillis();
Romain Guy06882f82009-06-10 13:36:04 -07007209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 lastKeyTime = curTime;
7211 nextKeyTime = curTime + LONG_WAIT;
7212 }
Romain Guy06882f82009-06-10 13:36:04 -07007213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007215 Slog.e(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 "Input thread received uncaught exception: " + e, e);
7217 }
7218 }
7219 }
7220 }
7221
7222 // -------------------------------------------------------------
7223 // Client Session State
7224 // -------------------------------------------------------------
7225
7226 private final class Session extends IWindowSession.Stub
7227 implements IBinder.DeathRecipient {
7228 final IInputMethodClient mClient;
7229 final IInputContext mInputContext;
7230 final int mUid;
7231 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007232 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 SurfaceSession mSurfaceSession;
7234 int mNumWindow = 0;
7235 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07007236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 /**
7238 * Current pointer move event being dispatched to client window... must
7239 * hold key lock to access.
7240 */
7241 QueuedEvent mPendingPointerMove;
7242 WindowState mPendingPointerWindow;
Romain Guy06882f82009-06-10 13:36:04 -07007243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 /**
7245 * Current trackball move event being dispatched to client window... must
7246 * hold key lock to access.
7247 */
7248 QueuedEvent mPendingTrackballMove;
7249 WindowState mPendingTrackballWindow;
7250
7251 public Session(IInputMethodClient client, IInputContext inputContext) {
7252 mClient = client;
7253 mInputContext = inputContext;
7254 mUid = Binder.getCallingUid();
7255 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007256 StringBuilder sb = new StringBuilder();
7257 sb.append("Session{");
7258 sb.append(Integer.toHexString(System.identityHashCode(this)));
7259 sb.append(" uid ");
7260 sb.append(mUid);
7261 sb.append("}");
7262 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07007263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 synchronized (mWindowMap) {
7265 if (mInputMethodManager == null && mHaveInputMethods) {
7266 IBinder b = ServiceManager.getService(
7267 Context.INPUT_METHOD_SERVICE);
7268 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
7269 }
7270 }
7271 long ident = Binder.clearCallingIdentity();
7272 try {
7273 // Note: it is safe to call in to the input method manager
7274 // here because we are not holding our lock.
7275 if (mInputMethodManager != null) {
7276 mInputMethodManager.addClient(client, inputContext,
7277 mUid, mPid);
7278 } else {
7279 client.setUsingInputMethod(false);
7280 }
7281 client.asBinder().linkToDeath(this, 0);
7282 } catch (RemoteException e) {
7283 // The caller has died, so we can just forget about this.
7284 try {
7285 if (mInputMethodManager != null) {
7286 mInputMethodManager.removeClient(client);
7287 }
7288 } catch (RemoteException ee) {
7289 }
7290 } finally {
7291 Binder.restoreCallingIdentity(ident);
7292 }
7293 }
Romain Guy06882f82009-06-10 13:36:04 -07007294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 @Override
7296 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
7297 throws RemoteException {
7298 try {
7299 return super.onTransact(code, data, reply, flags);
7300 } catch (RuntimeException e) {
7301 // Log all 'real' exceptions thrown to the caller
7302 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007303 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007304 }
7305 throw e;
7306 }
7307 }
7308
7309 public void binderDied() {
7310 // Note: it is safe to call in to the input method manager
7311 // here because we are not holding our lock.
7312 try {
7313 if (mInputMethodManager != null) {
7314 mInputMethodManager.removeClient(mClient);
7315 }
7316 } catch (RemoteException e) {
7317 }
7318 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07007319 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007320 mClientDead = true;
7321 killSessionLocked();
7322 }
7323 }
7324
7325 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007326 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
7327 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
7328 outInputChannel);
7329 }
7330
7331 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007333 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007334 }
Romain Guy06882f82009-06-10 13:36:04 -07007335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007336 public void remove(IWindow window) {
7337 removeWindow(this, window);
7338 }
Romain Guy06882f82009-06-10 13:36:04 -07007339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
7341 int requestedWidth, int requestedHeight, int viewFlags,
7342 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007343 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 return relayoutWindow(this, window, attrs,
7345 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007346 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007347 }
Romain Guy06882f82009-06-10 13:36:04 -07007348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007349 public void setTransparentRegion(IWindow window, Region region) {
7350 setTransparentRegionWindow(this, window, region);
7351 }
Romain Guy06882f82009-06-10 13:36:04 -07007352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007353 public void setInsets(IWindow window, int touchableInsets,
7354 Rect contentInsets, Rect visibleInsets) {
7355 setInsetsWindow(this, window, touchableInsets, contentInsets,
7356 visibleInsets);
7357 }
Romain Guy06882f82009-06-10 13:36:04 -07007358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007359 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
7360 getWindowDisplayFrame(this, window, outDisplayFrame);
7361 }
Romain Guy06882f82009-06-10 13:36:04 -07007362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007364 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 TAG, "IWindow finishDrawing called for " + window);
7366 finishDrawingWindow(this, window);
7367 }
7368
7369 public void finishKey(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007370 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 TAG, "IWindow finishKey called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007372 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7373 throw new IllegalStateException("Should not be called anymore.");
7374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 mKeyWaiter.finishedKey(this, window, false,
7376 KeyWaiter.RETURN_NOTHING);
7377 }
7378
7379 public MotionEvent getPendingPointerMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007380 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 TAG, "IWindow getPendingMotionEvent called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007382 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7383 throw new IllegalStateException("Should not be called anymore.");
7384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 return mKeyWaiter.finishedKey(this, window, false,
7386 KeyWaiter.RETURN_PENDING_POINTER);
7387 }
Romain Guy06882f82009-06-10 13:36:04 -07007388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 public MotionEvent getPendingTrackballMove(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007390 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 TAG, "IWindow getPendingMotionEvent called for " + window);
Jeff Brown349703e2010-06-22 01:27:15 -07007392 if (ENABLE_NATIVE_INPUT_DISPATCH) {
7393 throw new IllegalStateException("Should not be called anymore.");
7394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007395 return mKeyWaiter.finishedKey(this, window, false,
7396 KeyWaiter.RETURN_PENDING_TRACKBALL);
7397 }
7398
7399 public void setInTouchMode(boolean mode) {
7400 synchronized(mWindowMap) {
7401 mInTouchMode = mode;
7402 }
7403 }
7404
7405 public boolean getInTouchMode() {
7406 synchronized(mWindowMap) {
7407 return mInTouchMode;
7408 }
7409 }
7410
7411 public boolean performHapticFeedback(IWindow window, int effectId,
7412 boolean always) {
7413 synchronized(mWindowMap) {
7414 long ident = Binder.clearCallingIdentity();
7415 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007416 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007417 windowForClientLocked(this, window, true),
7418 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007419 } finally {
7420 Binder.restoreCallingIdentity(ident);
7421 }
7422 }
7423 }
Romain Guy06882f82009-06-10 13:36:04 -07007424
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007425 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007426 synchronized(mWindowMap) {
7427 long ident = Binder.clearCallingIdentity();
7428 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007429 setWindowWallpaperPositionLocked(
7430 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007431 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007432 } finally {
7433 Binder.restoreCallingIdentity(ident);
7434 }
7435 }
7436 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007437
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007438 public void wallpaperOffsetsComplete(IBinder window) {
7439 WindowManagerService.this.wallpaperOffsetsComplete(window);
7440 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007441
Dianne Hackborn75804932009-10-20 20:15:20 -07007442 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
7443 int z, Bundle extras, boolean sync) {
7444 synchronized(mWindowMap) {
7445 long ident = Binder.clearCallingIdentity();
7446 try {
7447 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007448 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07007449 action, x, y, z, extras, sync);
7450 } finally {
7451 Binder.restoreCallingIdentity(ident);
7452 }
7453 }
7454 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007455
Dianne Hackborn75804932009-10-20 20:15:20 -07007456 public void wallpaperCommandComplete(IBinder window, Bundle result) {
7457 WindowManagerService.this.wallpaperCommandComplete(window, result);
7458 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 void windowAddedLocked() {
7461 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007462 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007463 TAG, "First window added to " + this + ", creating SurfaceSession");
7464 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007465 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007466 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007467 mSessions.add(this);
7468 }
7469 mNumWindow++;
7470 }
7471
7472 void windowRemovedLocked() {
7473 mNumWindow--;
7474 killSessionLocked();
7475 }
Romain Guy06882f82009-06-10 13:36:04 -07007476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 void killSessionLocked() {
7478 if (mNumWindow <= 0 && mClientDead) {
7479 mSessions.remove(this);
7480 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007481 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007482 TAG, "Last window removed from " + this
7483 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007484 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007485 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 try {
7487 mSurfaceSession.kill();
7488 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007489 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007490 + mSurfaceSession + " in session " + this
7491 + ": " + e.toString());
7492 }
7493 mSurfaceSession = null;
7494 }
7495 }
7496 }
Romain Guy06882f82009-06-10 13:36:04 -07007497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007498 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007499 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
7500 pw.print(" mClientDead="); pw.print(mClientDead);
7501 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
7502 if (mPendingPointerWindow != null || mPendingPointerMove != null) {
7503 pw.print(prefix);
7504 pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
7505 pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
7506 }
7507 if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
7508 pw.print(prefix);
7509 pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
7510 pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
7511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 }
7513
7514 @Override
7515 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007516 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007517 }
7518 }
7519
7520 // -------------------------------------------------------------
7521 // Client Window State
7522 // -------------------------------------------------------------
7523
7524 private final class WindowState implements WindowManagerPolicy.WindowState {
7525 final Session mSession;
7526 final IWindow mClient;
7527 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07007528 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007529 AppWindowToken mAppToken;
7530 AppWindowToken mTargetAppToken;
7531 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
7532 final DeathRecipient mDeathRecipient;
7533 final WindowState mAttachedWindow;
7534 final ArrayList mChildWindows = new ArrayList();
7535 final int mBaseLayer;
7536 final int mSubLayer;
7537 final boolean mLayoutAttached;
7538 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007539 final boolean mIsWallpaper;
7540 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 int mViewVisibility;
7542 boolean mPolicyVisibility = true;
7543 boolean mPolicyVisibilityAfterAnim = true;
7544 boolean mAppFreezing;
7545 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007546 boolean mReportDestroySurface;
7547 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 boolean mAttachedHidden; // is our parent window hidden?
7549 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007550 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007551 int mRequestedWidth;
7552 int mRequestedHeight;
7553 int mLastRequestedWidth;
7554 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 int mLayer;
7556 int mAnimLayer;
7557 int mLastLayer;
7558 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007559 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007560 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007561
7562 WindowState mNextOutsideTouch;
Romain Guy06882f82009-06-10 13:36:04 -07007563
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007564 int mLayoutSeq = -1;
7565
7566 Configuration mConfiguration = null;
7567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007568 // Actual frame shown on-screen (may be modified by animation)
7569 final Rect mShownFrame = new Rect();
7570 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007572 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007573 * Set when we have changed the size of the surface, to know that
7574 * we must tell them application to resize (and thus redraw itself).
7575 */
7576 boolean mSurfaceResized;
7577
7578 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007579 * Insets that determine the actually visible area
7580 */
7581 final Rect mVisibleInsets = new Rect();
7582 final Rect mLastVisibleInsets = new Rect();
7583 boolean mVisibleInsetsChanged;
7584
7585 /**
7586 * Insets that are covered by system windows
7587 */
7588 final Rect mContentInsets = new Rect();
7589 final Rect mLastContentInsets = new Rect();
7590 boolean mContentInsetsChanged;
7591
7592 /**
7593 * Set to true if we are waiting for this window to receive its
7594 * given internal insets before laying out other windows based on it.
7595 */
7596 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07007597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007598 /**
7599 * These are the content insets that were given during layout for
7600 * this window, to be applied to windows behind it.
7601 */
7602 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007604 /**
7605 * These are the visible insets that were given during layout for
7606 * this window, to be applied to windows behind it.
7607 */
7608 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07007609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007610 /**
7611 * Flag indicating whether the touchable region should be adjusted by
7612 * the visible insets; if false the area outside the visible insets is
7613 * NOT touchable, so we must use those to adjust the frame during hit
7614 * tests.
7615 */
7616 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07007617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007618 // Current transformation being applied.
7619 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
7620 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
7621 float mHScale=1, mVScale=1;
7622 float mLastHScale=1, mLastVScale=1;
7623 final Matrix mTmpMatrix = new Matrix();
7624
7625 // "Real" frame that the application sees.
7626 final Rect mFrame = new Rect();
7627 final Rect mLastFrame = new Rect();
7628
7629 final Rect mContainingFrame = new Rect();
7630 final Rect mDisplayFrame = new Rect();
7631 final Rect mContentFrame = new Rect();
7632 final Rect mVisibleFrame = new Rect();
7633
7634 float mShownAlpha = 1;
7635 float mAlpha = 1;
7636 float mLastAlpha = 1;
7637
7638 // Set to true if, when the window gets displayed, it should perform
7639 // an enter animation.
7640 boolean mEnterAnimationPending;
7641
7642 // Currently running animation.
7643 boolean mAnimating;
7644 boolean mLocalAnimating;
7645 Animation mAnimation;
7646 boolean mAnimationIsEntrance;
7647 boolean mHasTransformation;
7648 boolean mHasLocalTransformation;
7649 final Transformation mTransformation = new Transformation();
7650
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007651 // If a window showing a wallpaper: the requested offset for the
7652 // wallpaper; if a wallpaper window: the currently applied offset.
7653 float mWallpaperX = -1;
7654 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007655
7656 // If a window showing a wallpaper: what fraction of the offset
7657 // range corresponds to a full virtual screen.
7658 float mWallpaperXStep = -1;
7659 float mWallpaperYStep = -1;
7660
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007661 // Wallpaper windows: pixels offset based on above variables.
7662 int mXOffset;
7663 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 // This is set after IWindowSession.relayout() has been called at
7666 // least once for the window. It allows us to detect the situation
7667 // where we don't yet have a surface, but should have one soon, so
7668 // we can give the window focus before waiting for the relayout.
7669 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 // This is set after the Surface has been created but before the
7672 // window has been drawn. During this time the surface is hidden.
7673 boolean mDrawPending;
7674
7675 // This is set after the window has finished drawing for the first
7676 // time but before its surface is shown. The surface will be
7677 // displayed when the next layout is run.
7678 boolean mCommitDrawPending;
7679
7680 // This is set during the time after the window's drawing has been
7681 // committed, and before its surface is actually shown. It is used
7682 // to delay showing the surface until all windows in a token are ready
7683 // to be shown.
7684 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 // Set when the window has been shown in the screen the first time.
7687 boolean mHasDrawn;
7688
7689 // Currently running an exit animation?
7690 boolean mExiting;
7691
7692 // Currently on the mDestroySurface list?
7693 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007695 // Completely remove from window manager after exit animation?
7696 boolean mRemoveOnExit;
7697
7698 // Set when the orientation is changing and this window has not yet
7699 // been updated for the new orientation.
7700 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 // Is this window now (or just being) removed?
7703 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007704
Dianne Hackborn16064f92010-03-25 00:47:24 -07007705 // For debugging, this is the last information given to the surface flinger.
7706 boolean mSurfaceShown;
7707 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7708 int mSurfaceLayer;
7709 float mSurfaceAlpha;
7710
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007711 // Input channel
7712 InputChannel mInputChannel;
7713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 WindowState(Session s, IWindow c, WindowToken token,
7715 WindowState attachedWindow, WindowManager.LayoutParams a,
7716 int viewVisibility) {
7717 mSession = s;
7718 mClient = c;
7719 mToken = token;
7720 mAttrs.copyFrom(a);
7721 mViewVisibility = viewVisibility;
7722 DeathRecipient deathRecipient = new DeathRecipient();
7723 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007724 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 TAG, "Window " + this + " client=" + c.asBinder()
7726 + " token=" + token + " (" + mAttrs.token + ")");
7727 try {
7728 c.asBinder().linkToDeath(deathRecipient, 0);
7729 } catch (RemoteException e) {
7730 mDeathRecipient = null;
7731 mAttachedWindow = null;
7732 mLayoutAttached = false;
7733 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007734 mIsWallpaper = false;
7735 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 mBaseLayer = 0;
7737 mSubLayer = 0;
7738 return;
7739 }
7740 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7743 mAttrs.type <= LAST_SUB_WINDOW)) {
7744 // The multiplier here is to reserve space for multiple
7745 // windows in the same type layer.
7746 mBaseLayer = mPolicy.windowTypeToLayerLw(
7747 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7748 + TYPE_LAYER_OFFSET;
7749 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7750 mAttachedWindow = attachedWindow;
7751 mAttachedWindow.mChildWindows.add(this);
7752 mLayoutAttached = mAttrs.type !=
7753 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7754 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7755 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007756 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7757 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007758 } else {
7759 // The multiplier here is to reserve space for multiple
7760 // windows in the same type layer.
7761 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7762 * TYPE_LAYER_MULTIPLIER
7763 + TYPE_LAYER_OFFSET;
7764 mSubLayer = 0;
7765 mAttachedWindow = null;
7766 mLayoutAttached = false;
7767 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7768 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007769 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7770 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007771 }
7772
7773 WindowState appWin = this;
7774 while (appWin.mAttachedWindow != null) {
7775 appWin = mAttachedWindow;
7776 }
7777 WindowToken appToken = appWin.mToken;
7778 while (appToken.appWindowToken == null) {
7779 WindowToken parent = mTokenMap.get(appToken.token);
7780 if (parent == null || appToken == parent) {
7781 break;
7782 }
7783 appToken = parent;
7784 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007785 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 mAppToken = appToken.appWindowToken;
7787
7788 mSurface = null;
7789 mRequestedWidth = 0;
7790 mRequestedHeight = 0;
7791 mLastRequestedWidth = 0;
7792 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007793 mXOffset = 0;
7794 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795 mLayer = 0;
7796 mAnimLayer = 0;
7797 mLastLayer = 0;
7798 }
7799
7800 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007801 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 TAG, "Attaching " + this + " token=" + mToken
7803 + ", list=" + mToken.windows);
7804 mSession.windowAddedLocked();
7805 }
7806
7807 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7808 mHaveFrame = true;
7809
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007810 final Rect container = mContainingFrame;
7811 container.set(pf);
7812
7813 final Rect display = mDisplayFrame;
7814 display.set(df);
7815
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007816 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007817 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007818 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7819 display.intersect(mCompatibleScreenFrame);
7820 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007821 }
7822
7823 final int pw = container.right - container.left;
7824 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007825
7826 int w,h;
7827 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7828 w = mAttrs.width < 0 ? pw : mAttrs.width;
7829 h = mAttrs.height< 0 ? ph : mAttrs.height;
7830 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007831 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7832 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007833 }
Romain Guy06882f82009-06-10 13:36:04 -07007834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 final Rect content = mContentFrame;
7836 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 final Rect visible = mVisibleFrame;
7839 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007842 final int fw = frame.width();
7843 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007845 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7846 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7847
7848 Gravity.apply(mAttrs.gravity, w, h, container,
7849 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7850 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7851
7852 //System.out.println("Out: " + mFrame);
7853
7854 // Now make sure the window fits in the overall display.
7855 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 // Make sure the content and visible frames are inside of the
7858 // final window frame.
7859 if (content.left < frame.left) content.left = frame.left;
7860 if (content.top < frame.top) content.top = frame.top;
7861 if (content.right > frame.right) content.right = frame.right;
7862 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7863 if (visible.left < frame.left) visible.left = frame.left;
7864 if (visible.top < frame.top) visible.top = frame.top;
7865 if (visible.right > frame.right) visible.right = frame.right;
7866 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007868 final Rect contentInsets = mContentInsets;
7869 contentInsets.left = content.left-frame.left;
7870 contentInsets.top = content.top-frame.top;
7871 contentInsets.right = frame.right-content.right;
7872 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874 final Rect visibleInsets = mVisibleInsets;
7875 visibleInsets.left = visible.left-frame.left;
7876 visibleInsets.top = visible.top-frame.top;
7877 visibleInsets.right = frame.right-visible.right;
7878 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007879
Dianne Hackborn284ac932009-08-28 10:34:25 -07007880 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7881 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007882 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007883 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 if (localLOGV) {
7886 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7887 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007888 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007889 + mRequestedWidth + ", mRequestedheight="
7890 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7891 + "): frame=" + mFrame.toShortString()
7892 + " ci=" + contentInsets.toShortString()
7893 + " vi=" + visibleInsets.toShortString());
7894 //}
7895 }
7896 }
Romain Guy06882f82009-06-10 13:36:04 -07007897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 public Rect getFrameLw() {
7899 return mFrame;
7900 }
7901
7902 public Rect getShownFrameLw() {
7903 return mShownFrame;
7904 }
7905
7906 public Rect getDisplayFrameLw() {
7907 return mDisplayFrame;
7908 }
7909
7910 public Rect getContentFrameLw() {
7911 return mContentFrame;
7912 }
7913
7914 public Rect getVisibleFrameLw() {
7915 return mVisibleFrame;
7916 }
7917
7918 public boolean getGivenInsetsPendingLw() {
7919 return mGivenInsetsPending;
7920 }
7921
7922 public Rect getGivenContentInsetsLw() {
7923 return mGivenContentInsets;
7924 }
Romain Guy06882f82009-06-10 13:36:04 -07007925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007926 public Rect getGivenVisibleInsetsLw() {
7927 return mGivenVisibleInsets;
7928 }
Romain Guy06882f82009-06-10 13:36:04 -07007929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007930 public WindowManager.LayoutParams getAttrs() {
7931 return mAttrs;
7932 }
7933
7934 public int getSurfaceLayer() {
7935 return mLayer;
7936 }
Romain Guy06882f82009-06-10 13:36:04 -07007937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007938 public IApplicationToken getAppToken() {
7939 return mAppToken != null ? mAppToken.appToken : null;
7940 }
Jeff Brown349703e2010-06-22 01:27:15 -07007941
7942 public long getInputDispatchingTimeoutNanos() {
7943 return mAppToken != null
7944 ? mAppToken.inputDispatchingTimeoutNanos
7945 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007947
7948 public boolean hasAppShownWindows() {
7949 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7950 }
7951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007952 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007953 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007954 TAG, "Setting animation in " + this + ": " + anim);
7955 mAnimating = false;
7956 mLocalAnimating = false;
7957 mAnimation = anim;
7958 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7959 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7960 }
7961
7962 public void clearAnimation() {
7963 if (mAnimation != null) {
7964 mAnimating = true;
7965 mLocalAnimating = false;
7966 mAnimation = null;
7967 }
7968 }
Romain Guy06882f82009-06-10 13:36:04 -07007969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 Surface createSurfaceLocked() {
7971 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007972 mReportDestroySurface = false;
7973 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007974 mDrawPending = true;
7975 mCommitDrawPending = false;
7976 mReadyToShow = false;
7977 if (mAppToken != null) {
7978 mAppToken.allDrawn = false;
7979 }
7980
7981 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07007982 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 flags |= Surface.PUSH_BUFFERS;
7984 }
7985
7986 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7987 flags |= Surface.SECURE;
7988 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007989 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007990 TAG, "Creating surface in session "
7991 + mSession.mSurfaceSession + " window " + this
7992 + " w=" + mFrame.width()
7993 + " h=" + mFrame.height() + " format="
7994 + mAttrs.format + " flags=" + flags);
7995
7996 int w = mFrame.width();
7997 int h = mFrame.height();
7998 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7999 // for a scaled surface, we always want the requested
8000 // size.
8001 w = mRequestedWidth;
8002 h = mRequestedHeight;
8003 }
8004
Romain Guy9825ec62009-10-01 00:58:09 -07008005 // Something is wrong and SurfaceFlinger will not like this,
8006 // try to revert to sane values
8007 if (w <= 0) w = 1;
8008 if (h <= 0) h = 1;
8009
Dianne Hackborn16064f92010-03-25 00:47:24 -07008010 mSurfaceShown = false;
8011 mSurfaceLayer = 0;
8012 mSurfaceAlpha = 1;
8013 mSurfaceX = 0;
8014 mSurfaceY = 0;
8015 mSurfaceW = w;
8016 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008017 try {
8018 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07008019 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08008020 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008021 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008022 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008023 + mSurface + " IN SESSION "
8024 + mSession.mSurfaceSession
8025 + ": pid=" + mSession.mPid + " format="
8026 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008027 + Integer.toHexString(flags)
8028 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008029 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008030 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008031 reclaimSomeSurfaceMemoryLocked(this, "create");
8032 return null;
8033 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008034 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008035 return null;
8036 }
Romain Guy06882f82009-06-10 13:36:04 -07008037
Joe Onorato8a9b2202010-02-26 18:56:32 -08008038 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 TAG, "Got surface: " + mSurface
8040 + ", set left=" + mFrame.left + " top=" + mFrame.top
8041 + ", animLayer=" + mAnimLayer);
8042 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008043 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008044 if (SHOW_TRANSACTIONS) logSurface(this,
8045 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
8046 mFrame.width() + "x" + mFrame.height() + "), layer=" +
8047 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048 }
8049 Surface.openTransaction();
8050 try {
8051 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008052 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07008053 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07008054 mSurface.setPosition(mSurfaceX, mSurfaceY);
8055 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008057 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008058 mSurface.hide();
8059 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008060 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 mSurface.setFlags(Surface.SURFACE_DITHER,
8062 Surface.SURFACE_DITHER);
8063 }
8064 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008065 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066 reclaimSomeSurfaceMemoryLocked(this, "create-init");
8067 }
8068 mLastHidden = true;
8069 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008070 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 Surface.closeTransaction();
8072 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008073 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008074 TAG, "Created surface " + this);
8075 }
8076 return mSurface;
8077 }
Romain Guy06882f82009-06-10 13:36:04 -07008078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008079 void destroySurfaceLocked() {
8080 // Window is no longer on-screen, so can no longer receive
8081 // key events... if we were waiting for it to finish
8082 // handling a key event, the wait is over!
Jeff Brown349703e2010-06-22 01:27:15 -07008083 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
8084 mKeyWaiter.finishedKey(mSession, mClient, true,
8085 KeyWaiter.RETURN_NOTHING);
8086 mKeyWaiter.releasePendingPointerLocked(mSession);
8087 mKeyWaiter.releasePendingTrackballLocked(mSession);
8088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089
8090 if (mAppToken != null && this == mAppToken.startingWindow) {
8091 mAppToken.startingDisplayed = false;
8092 }
Romain Guy06882f82009-06-10 13:36:04 -07008093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008095 mDrawPending = false;
8096 mCommitDrawPending = false;
8097 mReadyToShow = false;
8098
8099 int i = mChildWindows.size();
8100 while (i > 0) {
8101 i--;
8102 WindowState c = (WindowState)mChildWindows.get(i);
8103 c.mAttachedHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008104
8105 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8106 mInputMonitor.windowIsBecomingInvisibleLw(c);
8107 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008108 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008109
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008110 if (mReportDestroySurface) {
8111 mReportDestroySurface = false;
8112 mSurfacePendingDestroy = true;
8113 try {
8114 mClient.dispatchGetNewSurface();
8115 // We'll really destroy on the next time around.
8116 return;
8117 } catch (RemoteException e) {
8118 }
8119 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008122 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008123 RuntimeException e = null;
8124 if (!HIDE_STACK_CRAWLS) {
8125 e = new RuntimeException();
8126 e.fillInStackTrace();
8127 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008128 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008129 + mSurface + ", session " + mSession, e);
8130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008132 RuntimeException e = null;
8133 if (!HIDE_STACK_CRAWLS) {
8134 e = new RuntimeException();
8135 e.fillInStackTrace();
8136 }
8137 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008138 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008139 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008141 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142 + " surface " + mSurface + " session " + mSession
8143 + ": " + e.toString());
8144 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008145
Dianne Hackborn16064f92010-03-25 00:47:24 -07008146 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008147 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 }
8149 }
8150
8151 boolean finishDrawingLocked() {
8152 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008153 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 TAG, "finishDrawingLocked: " + mSurface);
8155 mCommitDrawPending = true;
8156 mDrawPending = false;
8157 return true;
8158 }
8159 return false;
8160 }
8161
8162 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008163 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008164 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008165 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008166 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008167 }
8168 mCommitDrawPending = false;
8169 mReadyToShow = true;
8170 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
8171 final AppWindowToken atoken = mAppToken;
8172 if (atoken == null || atoken.allDrawn || starting) {
8173 performShowLocked();
8174 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008175 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 }
8177
8178 // This must be called while inside a transaction.
8179 boolean performShowLocked() {
8180 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008181 RuntimeException e = null;
8182 if (!HIDE_STACK_CRAWLS) {
8183 e = new RuntimeException();
8184 e.fillInStackTrace();
8185 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008186 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008187 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
8188 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
8189 }
8190 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008191 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
8192 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008193 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 + " during animation: policyVis=" + mPolicyVisibility
8195 + " attHidden=" + mAttachedHidden
8196 + " tok.hiddenRequested="
8197 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07008198 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 + (mAppToken != null ? mAppToken.hidden : false)
8200 + " animating=" + mAnimating
8201 + " tok animating="
8202 + (mAppToken != null ? mAppToken.animating : false));
8203 if (!showSurfaceRobustlyLocked(this)) {
8204 return false;
8205 }
8206 mLastAlpha = -1;
8207 mHasDrawn = true;
8208 mLastHidden = false;
8209 mReadyToShow = false;
8210 enableScreenIfNeededLocked();
8211
8212 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07008213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008214 int i = mChildWindows.size();
8215 while (i > 0) {
8216 i--;
8217 WindowState c = (WindowState)mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008218 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07008220 if (c.mSurface != null) {
8221 c.performShowLocked();
8222 // It hadn't been shown, which means layout not
8223 // performed on it, so now we want to make sure to
8224 // do a layout. If called from within the transaction
8225 // loop, this will cause it to restart with a new
8226 // layout.
8227 mLayoutNeeded = true;
8228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229 }
8230 }
Romain Guy06882f82009-06-10 13:36:04 -07008231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232 if (mAttrs.type != TYPE_APPLICATION_STARTING
8233 && mAppToken != null) {
8234 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008235
Dianne Hackborn248b1882009-09-16 16:46:44 -07008236 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008237 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008238 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008239 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07008240 // If this initial window is animating, stop it -- we
8241 // will do an animation to reveal it from behind the
8242 // starting window, so there is no need for it to also
8243 // be doing its own stuff.
8244 if (mAnimation != null) {
8245 mAnimation = null;
8246 // Make sure we clean up the animation.
8247 mAnimating = true;
8248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249 mFinishedStarting.add(mAppToken);
8250 mH.sendEmptyMessage(H.FINISHED_STARTING);
8251 }
8252 mAppToken.updateReportedVisibilityLocked();
8253 }
8254 }
8255 return true;
8256 }
Romain Guy06882f82009-06-10 13:36:04 -07008257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008258 // This must be called while inside a transaction. Returns true if
8259 // there is more animation to run.
8260 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008261 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008262 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008264 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
8265 mHasTransformation = true;
8266 mHasLocalTransformation = true;
8267 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008268 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269 TAG, "Starting animation in " + this +
8270 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
8271 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
8272 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
8273 mAnimation.setStartTime(currentTime);
8274 mLocalAnimating = true;
8275 mAnimating = true;
8276 }
8277 mTransformation.clear();
8278 final boolean more = mAnimation.getTransformation(
8279 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008280 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008281 TAG, "Stepped animation in " + this +
8282 ": more=" + more + ", xform=" + mTransformation);
8283 if (more) {
8284 // we're not done!
8285 return true;
8286 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008287 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008288 TAG, "Finished animation in " + this +
8289 " @ " + currentTime);
8290 mAnimation = null;
8291 //WindowManagerService.this.dump();
8292 }
8293 mHasLocalTransformation = false;
8294 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008295 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 // When our app token is animating, we kind-of pretend like
8297 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
8298 // part of this check means that we will only do this if
8299 // our window is not currently exiting, or it is not
8300 // locally animating itself. The idea being that one that
8301 // is exiting and doing a local animation should be removed
8302 // once that animation is done.
8303 mAnimating = true;
8304 mHasTransformation = true;
8305 mTransformation.clear();
8306 return false;
8307 } else if (mHasTransformation) {
8308 // Little trick to get through the path below to act like
8309 // we have finished an animation.
8310 mAnimating = true;
8311 } else if (isAnimating()) {
8312 mAnimating = true;
8313 }
8314 } else if (mAnimation != null) {
8315 // If the display is frozen, and there is a pending animation,
8316 // clear it and make sure we run the cleanup code.
8317 mAnimating = true;
8318 mLocalAnimating = true;
8319 mAnimation = null;
8320 }
Romain Guy06882f82009-06-10 13:36:04 -07008321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322 if (!mAnimating && !mLocalAnimating) {
8323 return false;
8324 }
8325
Joe Onorato8a9b2202010-02-26 18:56:32 -08008326 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008327 TAG, "Animation done in " + this + ": exiting=" + mExiting
8328 + ", reportedVisible="
8329 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07008330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008331 mAnimating = false;
8332 mLocalAnimating = false;
8333 mAnimation = null;
8334 mAnimLayer = mLayer;
8335 if (mIsImWindow) {
8336 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008337 } else if (mIsWallpaper) {
8338 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008340 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341 + " anim layer: " + mAnimLayer);
8342 mHasTransformation = false;
8343 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008344 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
8345 if (DEBUG_VISIBILITY) {
8346 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
8347 + mPolicyVisibilityAfterAnim);
8348 }
8349 mPolicyVisibility = mPolicyVisibilityAfterAnim;
8350 if (!mPolicyVisibility) {
8351 if (mCurrentFocus == this) {
8352 mFocusMayChange = true;
8353 }
8354 // Window is no longer visible -- make sure if we were waiting
8355 // for it to be displayed before enabling the display, that
8356 // we allow the display to be enabled now.
8357 enableScreenIfNeededLocked();
8358 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008360 mTransformation.clear();
8361 if (mHasDrawn
8362 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
8363 && mAppToken != null
8364 && mAppToken.firstWindowDrawn
8365 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008366 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008367 + mToken + ": first real window done animating");
8368 mFinishedStarting.add(mAppToken);
8369 mH.sendEmptyMessage(H.FINISHED_STARTING);
8370 }
Romain Guy06882f82009-06-10 13:36:04 -07008371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008372 finishExit();
8373
8374 if (mAppToken != null) {
8375 mAppToken.updateReportedVisibilityLocked();
8376 }
8377
8378 return false;
8379 }
8380
8381 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008382 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383 TAG, "finishExit in " + this
8384 + ": exiting=" + mExiting
8385 + " remove=" + mRemoveOnExit
8386 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07008387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 final int N = mChildWindows.size();
8389 for (int i=0; i<N; i++) {
8390 ((WindowState)mChildWindows.get(i)).finishExit();
8391 }
Romain Guy06882f82009-06-10 13:36:04 -07008392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008393 if (!mExiting) {
8394 return;
8395 }
Romain Guy06882f82009-06-10 13:36:04 -07008396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 if (isWindowAnimating()) {
8398 return;
8399 }
8400
Joe Onorato8a9b2202010-02-26 18:56:32 -08008401 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 TAG, "Exit animation finished in " + this
8403 + ": remove=" + mRemoveOnExit);
8404 if (mSurface != null) {
8405 mDestroySurface.add(this);
8406 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008407 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008408 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008409 try {
8410 mSurface.hide();
8411 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008412 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008413 }
8414 mLastHidden = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008415
8416 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8417 for (int i=0; i<N; i++) {
8418 mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i));
8419 }
8420 } else {
8421 mKeyWaiter.releasePendingPointerLocked(mSession);
8422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008423 }
8424 mExiting = false;
8425 if (mRemoveOnExit) {
8426 mPendingRemove.add(this);
8427 mRemoveOnExit = false;
8428 }
8429 }
Romain Guy06882f82009-06-10 13:36:04 -07008430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008431 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
8432 if (dsdx < .99999f || dsdx > 1.00001f) return false;
8433 if (dtdy < .99999f || dtdy > 1.00001f) return false;
8434 if (dtdx < -.000001f || dtdx > .000001f) return false;
8435 if (dsdy < -.000001f || dsdy > .000001f) return false;
8436 return true;
8437 }
Romain Guy06882f82009-06-10 13:36:04 -07008438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008439 void computeShownFrameLocked() {
8440 final boolean selfTransformation = mHasLocalTransformation;
8441 Transformation attachedTransformation =
8442 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
8443 ? mAttachedWindow.mTransformation : null;
8444 Transformation appTransformation =
8445 (mAppToken != null && mAppToken.hasTransformation)
8446 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008447
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008448 // Wallpapers are animated based on the "real" window they
8449 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008450 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07008451 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07008452 if (mWallpaperTarget.mHasLocalTransformation &&
8453 mWallpaperTarget.mAnimation != null &&
8454 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008455 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008456 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008457 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008458 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008459 }
8460 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07008461 mWallpaperTarget.mAppToken.hasTransformation &&
8462 mWallpaperTarget.mAppToken.animation != null &&
8463 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008464 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07008465 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008466 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07008467 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008468 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008469 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008471 if (selfTransformation || attachedTransformation != null
8472 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07008473 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 final Rect frame = mFrame;
8475 final float tmpFloats[] = mTmpFloats;
8476 final Matrix tmpMatrix = mTmpMatrix;
8477
8478 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07008479 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008480 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008481 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07008483 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008484 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008485 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008486 }
8487 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07008488 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008489 }
8490
8491 // "convert" it into SurfaceFlinger's format
8492 // (a 2x2 matrix + an offset)
8493 // Here we must not transform the position of the surface
8494 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008495 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07008496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008497 tmpMatrix.getValues(tmpFloats);
8498 mDsDx = tmpFloats[Matrix.MSCALE_X];
8499 mDtDx = tmpFloats[Matrix.MSKEW_X];
8500 mDsDy = tmpFloats[Matrix.MSKEW_Y];
8501 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008502 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
8503 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 int w = frame.width();
8505 int h = frame.height();
8506 mShownFrame.set(x, y, x+w, y+h);
8507
8508 // Now set the alpha... but because our current hardware
8509 // can't do alpha transformation on a non-opaque surface,
8510 // turn it off if we are running an animation that is also
8511 // transforming since it is more important to have that
8512 // animation be smooth.
8513 mShownAlpha = mAlpha;
8514 if (!mLimitedAlphaCompositing
8515 || (!PixelFormat.formatHasAlpha(mAttrs.format)
8516 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
8517 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008518 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008519 if (selfTransformation) {
8520 mShownAlpha *= mTransformation.getAlpha();
8521 }
8522 if (attachedTransformation != null) {
8523 mShownAlpha *= attachedTransformation.getAlpha();
8524 }
8525 if (appTransformation != null) {
8526 mShownAlpha *= appTransformation.getAlpha();
8527 }
8528 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008529 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008530 }
Romain Guy06882f82009-06-10 13:36:04 -07008531
Joe Onorato8a9b2202010-02-26 18:56:32 -08008532 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 TAG, "Continuing animation in " + this +
8534 ": " + mShownFrame +
8535 ", alpha=" + mTransformation.getAlpha());
8536 return;
8537 }
Romain Guy06882f82009-06-10 13:36:04 -07008538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008540 if (mXOffset != 0 || mYOffset != 0) {
8541 mShownFrame.offset(mXOffset, mYOffset);
8542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 mShownAlpha = mAlpha;
8544 mDsDx = 1;
8545 mDtDx = 0;
8546 mDsDy = 0;
8547 mDtDy = 1;
8548 }
Romain Guy06882f82009-06-10 13:36:04 -07008549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008550 /**
8551 * Is this window visible? It is not visible if there is no
8552 * surface, or we are in the process of running an exit animation
8553 * that will remove the surface, or its app token has been hidden.
8554 */
8555 public boolean isVisibleLw() {
8556 final AppWindowToken atoken = mAppToken;
8557 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8558 && (atoken == null || !atoken.hiddenRequested)
8559 && !mExiting && !mDestroying;
8560 }
8561
8562 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008563 * Like {@link #isVisibleLw}, but also counts a window that is currently
8564 * "hidden" behind the keyguard as visible. This allows us to apply
8565 * things like window flags that impact the keyguard.
8566 * XXX I am starting to think we need to have ANOTHER visibility flag
8567 * for this "hidden behind keyguard" state rather than overloading
8568 * mPolicyVisibility. Ungh.
8569 */
8570 public boolean isVisibleOrBehindKeyguardLw() {
8571 final AppWindowToken atoken = mAppToken;
8572 return mSurface != null && !mAttachedHidden
8573 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008574 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07008575 && !mExiting && !mDestroying;
8576 }
8577
8578 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 * Is this window visible, ignoring its app token? It is not visible
8580 * if there is no surface, or we are in the process of running an exit animation
8581 * that will remove the surface.
8582 */
8583 public boolean isWinVisibleLw() {
8584 final AppWindowToken atoken = mAppToken;
8585 return mSurface != null && mPolicyVisibility && !mAttachedHidden
8586 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
8587 && !mExiting && !mDestroying;
8588 }
8589
8590 /**
8591 * The same as isVisible(), but follows the current hidden state of
8592 * the associated app token, not the pending requested hidden state.
8593 */
8594 boolean isVisibleNow() {
8595 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07008596 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 }
8598
8599 /**
8600 * Same as isVisible(), but we also count it as visible between the
8601 * call to IWindowSession.add() and the first relayout().
8602 */
8603 boolean isVisibleOrAdding() {
8604 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008605 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
8607 && mPolicyVisibility && !mAttachedHidden
8608 && (atoken == null || !atoken.hiddenRequested)
8609 && !mExiting && !mDestroying;
8610 }
8611
8612 /**
8613 * Is this window currently on-screen? It is on-screen either if it
8614 * is visible or it is currently running an animation before no longer
8615 * being visible.
8616 */
8617 boolean isOnScreen() {
8618 final AppWindowToken atoken = mAppToken;
8619 if (atoken != null) {
8620 return mSurface != null && mPolicyVisibility && !mDestroying
8621 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008622 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008623 } else {
8624 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008625 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 }
8627 }
Romain Guy06882f82009-06-10 13:36:04 -07008628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008629 /**
8630 * Like isOnScreen(), but we don't return true if the window is part
8631 * of a transition that has not yet been started.
8632 */
8633 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008634 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008635 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008636 return false;
8637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008639 final boolean animating = atoken != null
8640 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008642 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8643 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008644 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008645 }
8646
8647 /** Is the window or its container currently animating? */
8648 boolean isAnimating() {
8649 final WindowState attached = mAttachedWindow;
8650 final AppWindowToken atoken = mAppToken;
8651 return mAnimation != null
8652 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008653 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008654 (atoken.animation != null
8655 || atoken.inPendingTransaction));
8656 }
8657
8658 /** Is this window currently animating? */
8659 boolean isWindowAnimating() {
8660 return mAnimation != null;
8661 }
8662
8663 /**
8664 * Like isOnScreen, but returns false if the surface hasn't yet
8665 * been drawn.
8666 */
8667 public boolean isDisplayedLw() {
8668 final AppWindowToken atoken = mAppToken;
8669 return mSurface != null && mPolicyVisibility && !mDestroying
8670 && !mDrawPending && !mCommitDrawPending
8671 && ((!mAttachedHidden &&
8672 (atoken == null || !atoken.hiddenRequested))
8673 || mAnimating);
8674 }
8675
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008676 /**
8677 * Returns true if the window has a surface that it has drawn a
8678 * complete UI in to.
8679 */
8680 public boolean isDrawnLw() {
8681 final AppWindowToken atoken = mAppToken;
8682 return mSurface != null && !mDestroying
8683 && !mDrawPending && !mCommitDrawPending;
8684 }
8685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 public boolean fillsScreenLw(int screenWidth, int screenHeight,
8687 boolean shownFrame, boolean onlyOpaque) {
8688 if (mSurface == null) {
8689 return false;
8690 }
8691 if (mAppToken != null && !mAppToken.appFullscreen) {
8692 return false;
8693 }
8694 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
8695 return false;
8696 }
8697 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008698
8699 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
8700 return frame.left <= mCompatibleScreenFrame.left &&
8701 frame.top <= mCompatibleScreenFrame.top &&
8702 frame.right >= mCompatibleScreenFrame.right &&
8703 frame.bottom >= mCompatibleScreenFrame.bottom;
8704 } else {
8705 return frame.left <= 0 && frame.top <= 0
8706 && frame.right >= screenWidth
8707 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 }
Romain Guy06882f82009-06-10 13:36:04 -07008710
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008711 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008712 * Return true if the window is opaque and fully drawn. This indicates
8713 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008714 */
8715 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008716 return (mAttrs.format == PixelFormat.OPAQUE
8717 || mAttrs.type == TYPE_WALLPAPER)
8718 && mSurface != null && mAnimation == null
8719 && (mAppToken == null || mAppToken.animation == null)
8720 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008721 }
8722
8723 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8724 return
8725 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008726 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8727 // only if it's visible
8728 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008729 // and only if the application fills the compatible screen
8730 mFrame.left <= mCompatibleScreenFrame.left &&
8731 mFrame.top <= mCompatibleScreenFrame.top &&
8732 mFrame.right >= mCompatibleScreenFrame.right &&
8733 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008734 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008735 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008736 }
8737
8738 boolean isFullscreen(int screenWidth, int screenHeight) {
8739 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008740 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008741 }
8742
8743 void removeLocked() {
8744 if (mAttachedWindow != null) {
8745 mAttachedWindow.mChildWindows.remove(this);
8746 }
8747 destroySurfaceLocked();
8748 mSession.windowRemovedLocked();
8749 try {
8750 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8751 } catch (RuntimeException e) {
8752 // Ignore if it has already been removed (usually because
8753 // we are doing this as part of processing a death note.)
8754 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008755
8756 if (ENABLE_NATIVE_INPUT_DISPATCH) {
8757 if (mInputChannel != null) {
8758 mInputManager.unregisterInputChannel(mInputChannel);
8759
8760 mInputChannel.dispose();
8761 mInputChannel = null;
8762 }
8763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764 }
8765
8766 private class DeathRecipient implements IBinder.DeathRecipient {
8767 public void binderDied() {
8768 try {
8769 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008770 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008771 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 if (win != null) {
8773 removeWindowLocked(mSession, win);
8774 }
8775 }
8776 } catch (IllegalArgumentException ex) {
8777 // This will happen if the window has already been
8778 // removed.
8779 }
8780 }
8781 }
8782
8783 /** Returns true if this window desires key events. */
8784 public final boolean canReceiveKeys() {
8785 return isVisibleOrAdding()
8786 && (mViewVisibility == View.VISIBLE)
8787 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8788 }
8789
8790 public boolean hasDrawnLw() {
8791 return mHasDrawn;
8792 }
8793
8794 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008795 return showLw(doAnimation, true);
8796 }
8797
8798 boolean showLw(boolean doAnimation, boolean requestAnim) {
8799 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8800 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008801 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008802 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008803 if (doAnimation) {
8804 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8805 + mPolicyVisibility + " mAnimation=" + mAnimation);
8806 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8807 doAnimation = false;
8808 } else if (mPolicyVisibility && mAnimation == null) {
8809 // Check for the case where we are currently visible and
8810 // not animating; we do not want to do animation at such a
8811 // point to become visible when we already are.
8812 doAnimation = false;
8813 }
8814 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008815 mPolicyVisibility = true;
8816 mPolicyVisibilityAfterAnim = true;
8817 if (doAnimation) {
8818 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8819 }
8820 if (requestAnim) {
8821 requestAnimationLocked(0);
8822 }
8823 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008824 }
8825
8826 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008827 return hideLw(doAnimation, true);
8828 }
8829
8830 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008831 if (doAnimation) {
8832 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8833 doAnimation = false;
8834 }
8835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008836 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8837 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008838 if (!current) {
8839 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008840 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008841 if (doAnimation) {
8842 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8843 if (mAnimation == null) {
8844 doAnimation = false;
8845 }
8846 }
8847 if (doAnimation) {
8848 mPolicyVisibilityAfterAnim = false;
8849 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008850 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008851 mPolicyVisibilityAfterAnim = false;
8852 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008853 // Window is no longer visible -- make sure if we were waiting
8854 // for it to be displayed before enabling the display, that
8855 // we allow the display to be enabled now.
8856 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008857 if (mCurrentFocus == this) {
8858 mFocusMayChange = true;
8859 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008860 }
8861 if (requestAnim) {
8862 requestAnimationLocked(0);
8863 }
8864 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008865 }
8866
8867 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008868 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8869 pw.print(" mClient="); pw.println(mClient.asBinder());
8870 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8871 if (mAttachedWindow != null || mLayoutAttached) {
8872 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8873 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8874 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008875 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8876 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8877 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008878 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8879 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008880 }
8881 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8882 pw.print(" mSubLayer="); pw.print(mSubLayer);
8883 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8884 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8885 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8886 pw.print("="); pw.print(mAnimLayer);
8887 pw.print(" mLastLayer="); pw.println(mLastLayer);
8888 if (mSurface != null) {
8889 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008890 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8891 pw.print(" layer="); pw.print(mSurfaceLayer);
8892 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8893 pw.print(" rect=("); pw.print(mSurfaceX);
8894 pw.print(","); pw.print(mSurfaceY);
8895 pw.print(") "); pw.print(mSurfaceW);
8896 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008897 }
8898 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8899 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8900 if (mAppToken != null) {
8901 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8902 }
8903 if (mTargetAppToken != null) {
8904 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8905 }
8906 pw.print(prefix); pw.print("mViewVisibility=0x");
8907 pw.print(Integer.toHexString(mViewVisibility));
8908 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008909 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8910 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008911 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8912 pw.print(prefix); pw.print("mPolicyVisibility=");
8913 pw.print(mPolicyVisibility);
8914 pw.print(" mPolicyVisibilityAfterAnim=");
8915 pw.print(mPolicyVisibilityAfterAnim);
8916 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8917 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008918 if (!mRelayoutCalled) {
8919 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8920 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008921 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008922 pw.print(" h="); pw.print(mRequestedHeight);
8923 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008924 if (mXOffset != 0 || mYOffset != 0) {
8925 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8926 pw.print(" y="); pw.println(mYOffset);
8927 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008928 pw.print(prefix); pw.print("mGivenContentInsets=");
8929 mGivenContentInsets.printShortString(pw);
8930 pw.print(" mGivenVisibleInsets=");
8931 mGivenVisibleInsets.printShortString(pw);
8932 pw.println();
8933 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8934 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8935 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8936 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008937 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008938 pw.print(prefix); pw.print("mShownFrame=");
8939 mShownFrame.printShortString(pw);
8940 pw.print(" last="); mLastShownFrame.printShortString(pw);
8941 pw.println();
8942 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8943 pw.print(" last="); mLastFrame.printShortString(pw);
8944 pw.println();
8945 pw.print(prefix); pw.print("mContainingFrame=");
8946 mContainingFrame.printShortString(pw);
8947 pw.print(" mDisplayFrame=");
8948 mDisplayFrame.printShortString(pw);
8949 pw.println();
8950 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8951 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8952 pw.println();
8953 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8954 pw.print(" last="); mLastContentInsets.printShortString(pw);
8955 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8956 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8957 pw.println();
8958 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8959 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8960 pw.print(" mAlpha="); pw.print(mAlpha);
8961 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8962 }
8963 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8964 || mAnimation != null) {
8965 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8966 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8967 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8968 pw.print(" mAnimation="); pw.println(mAnimation);
8969 }
8970 if (mHasTransformation || mHasLocalTransformation) {
8971 pw.print(prefix); pw.print("XForm: has=");
8972 pw.print(mHasTransformation);
8973 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8974 pw.print(" "); mTransformation.printShortString(pw);
8975 pw.println();
8976 }
8977 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8978 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8979 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8980 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8981 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8982 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8983 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8984 pw.print(" mDestroying="); pw.print(mDestroying);
8985 pw.print(" mRemoved="); pw.println(mRemoved);
8986 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008987 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008988 pw.print(prefix); pw.print("mOrientationChanging=");
8989 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008990 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8991 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008992 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008993 if (mHScale != 1 || mVScale != 1) {
8994 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8995 pw.print(" mVScale="); pw.println(mVScale);
8996 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008997 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008998 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8999 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
9000 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08009001 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
9002 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
9003 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
9004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009006
9007 String makeInputChannelName() {
9008 return Integer.toHexString(System.identityHashCode(this))
9009 + " " + mAttrs.getTitle();
9010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011
9012 @Override
9013 public String toString() {
9014 return "Window{"
9015 + Integer.toHexString(System.identityHashCode(this))
9016 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
9017 }
9018 }
Romain Guy06882f82009-06-10 13:36:04 -07009019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 // -------------------------------------------------------------
9021 // Window Token State
9022 // -------------------------------------------------------------
9023
9024 class WindowToken {
9025 // The actual token.
9026 final IBinder token;
9027
9028 // The type of window this token is for, as per WindowManager.LayoutParams.
9029 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07009030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009031 // Set if this token was explicitly added by a client, so should
9032 // not be removed when all windows are removed.
9033 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07009034
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009035 // For printing.
9036 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07009037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038 // If this is an AppWindowToken, this is non-null.
9039 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07009040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009041 // All of the windows associated with this token.
9042 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
9043
9044 // Is key dispatching paused for this token?
9045 boolean paused = false;
9046
9047 // Should this token's windows be hidden?
9048 boolean hidden;
9049
9050 // Temporary for finding which tokens no longer have visible windows.
9051 boolean hasVisible;
9052
Dianne Hackborna8f60182009-09-01 19:01:50 -07009053 // Set to true when this token is in a pending transaction where it
9054 // will be shown.
9055 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009056
Dianne Hackborna8f60182009-09-01 19:01:50 -07009057 // Set to true when this token is in a pending transaction where it
9058 // will be hidden.
9059 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009060
Dianne Hackborna8f60182009-09-01 19:01:50 -07009061 // Set to true when this token is in a pending transaction where its
9062 // windows will be put to the bottom of the list.
9063 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009064
Dianne Hackborna8f60182009-09-01 19:01:50 -07009065 // Set to true when this token is in a pending transaction where its
9066 // windows will be put to the top of the list.
9067 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 WindowToken(IBinder _token, int type, boolean _explicit) {
9070 token = _token;
9071 windowType = type;
9072 explicit = _explicit;
9073 }
9074
9075 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009076 pw.print(prefix); pw.print("token="); pw.println(token);
9077 pw.print(prefix); pw.print("windows="); pw.println(windows);
9078 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
9079 pw.print(" hidden="); pw.print(hidden);
9080 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009081 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
9082 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
9083 pw.print(" waitingToHide="); pw.print(waitingToHide);
9084 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
9085 pw.print(" sendingToTop="); pw.println(sendingToTop);
9086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009087 }
9088
9089 @Override
9090 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009091 if (stringName == null) {
9092 StringBuilder sb = new StringBuilder();
9093 sb.append("WindowToken{");
9094 sb.append(Integer.toHexString(System.identityHashCode(this)));
9095 sb.append(" token="); sb.append(token); sb.append('}');
9096 stringName = sb.toString();
9097 }
9098 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 }
9100 };
9101
9102 class AppWindowToken extends WindowToken {
9103 // Non-null only for application tokens.
9104 final IApplicationToken appToken;
9105
9106 // All of the windows and child windows that are included in this
9107 // application token. Note this list is NOT sorted!
9108 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
9109
9110 int groupId = -1;
9111 boolean appFullscreen;
9112 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07009113
9114 // The input dispatching timeout for this application token in nanoseconds.
9115 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07009116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009117 // These are used for determining when all windows associated with
9118 // an activity have been drawn, so they can be made visible together
9119 // at the same time.
9120 int lastTransactionSequence = mTransactionSequence-1;
9121 int numInterestingWindows;
9122 int numDrawnWindows;
9123 boolean inPendingTransaction;
9124 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07009125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126 // Is this token going to be hidden in a little while? If so, it
9127 // won't be taken into account for setting the screen orientation.
9128 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07009129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009130 // Is this window's surface needed? This is almost like hidden, except
9131 // it will sometimes be true a little earlier: when the token has
9132 // been shown, but is still waiting for its app transition to execute
9133 // before making its windows shown.
9134 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07009135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009136 // Have we told the window clients to hide themselves?
9137 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07009138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139 // Last visibility state we reported to the app token.
9140 boolean reportedVisible;
9141
9142 // Set to true when the token has been removed from the window mgr.
9143 boolean removed;
9144
9145 // Have we been asked to have this token keep the screen frozen?
9146 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07009147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148 boolean animating;
9149 Animation animation;
9150 boolean hasTransformation;
9151 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07009152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009153 // Offset to the window of all layers in the token, for use by
9154 // AppWindowToken animations.
9155 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07009156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009157 // Information about an application starting window if displayed.
9158 StartingData startingData;
9159 WindowState startingWindow;
9160 View startingView;
9161 boolean startingDisplayed;
9162 boolean startingMoved;
9163 boolean firstWindowDrawn;
9164
9165 AppWindowToken(IApplicationToken _token) {
9166 super(_token.asBinder(),
9167 WindowManager.LayoutParams.TYPE_APPLICATION, true);
9168 appWindowToken = this;
9169 appToken = _token;
9170 }
Romain Guy06882f82009-06-10 13:36:04 -07009171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009173 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009174 TAG, "Setting animation in " + this + ": " + anim);
9175 animation = anim;
9176 animating = false;
9177 anim.restrictDuration(MAX_ANIMATION_DURATION);
9178 anim.scaleCurrentDuration(mTransitionAnimationScale);
9179 int zorder = anim.getZAdjustment();
9180 int adj = 0;
9181 if (zorder == Animation.ZORDER_TOP) {
9182 adj = TYPE_LAYER_OFFSET;
9183 } else if (zorder == Animation.ZORDER_BOTTOM) {
9184 adj = -TYPE_LAYER_OFFSET;
9185 }
Romain Guy06882f82009-06-10 13:36:04 -07009186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 if (animLayerAdjustment != adj) {
9188 animLayerAdjustment = adj;
9189 updateLayers();
9190 }
9191 }
Romain Guy06882f82009-06-10 13:36:04 -07009192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009193 public void setDummyAnimation() {
9194 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009195 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009196 TAG, "Setting dummy animation in " + this);
9197 animation = sDummyAnimation;
9198 }
9199 }
9200
9201 public void clearAnimation() {
9202 if (animation != null) {
9203 animation = null;
9204 animating = true;
9205 }
9206 }
Romain Guy06882f82009-06-10 13:36:04 -07009207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208 void updateLayers() {
9209 final int N = allAppWindows.size();
9210 final int adj = animLayerAdjustment;
9211 for (int i=0; i<N; i++) {
9212 WindowState w = allAppWindows.get(i);
9213 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009214 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009215 + w.mAnimLayer);
9216 if (w == mInputMethodTarget) {
9217 setInputMethodAnimLayerAdjustment(adj);
9218 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009219 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07009220 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 }
9223 }
Romain Guy06882f82009-06-10 13:36:04 -07009224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009225 void sendAppVisibilityToClients() {
9226 final int N = allAppWindows.size();
9227 for (int i=0; i<N; i++) {
9228 WindowState win = allAppWindows.get(i);
9229 if (win == startingWindow && clientHidden) {
9230 // Don't hide the starting window.
9231 continue;
9232 }
9233 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009234 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009235 "Setting visibility of " + win + ": " + (!clientHidden));
9236 win.mClient.dispatchAppVisibility(!clientHidden);
9237 } catch (RemoteException e) {
9238 }
9239 }
9240 }
Romain Guy06882f82009-06-10 13:36:04 -07009241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 void showAllWindowsLocked() {
9243 final int NW = allAppWindows.size();
9244 for (int i=0; i<NW; i++) {
9245 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009246 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 "performing show on: " + w);
9248 w.performShowLocked();
9249 }
9250 }
Romain Guy06882f82009-06-10 13:36:04 -07009251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 // This must be called while inside a transaction.
9253 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009254 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07009256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009257 if (animation == sDummyAnimation) {
9258 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009259 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009260 // when it is really time to animate, this will be set to
9261 // a real animation and the next call will execute normally.
9262 return false;
9263 }
Romain Guy06882f82009-06-10 13:36:04 -07009264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 if ((allDrawn || animating || startingDisplayed) && animation != null) {
9266 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009267 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268 TAG, "Starting animation in " + this +
9269 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
9270 + " scale=" + mTransitionAnimationScale
9271 + " allDrawn=" + allDrawn + " animating=" + animating);
9272 animation.initialize(dw, dh, dw, dh);
9273 animation.setStartTime(currentTime);
9274 animating = true;
9275 }
9276 transformation.clear();
9277 final boolean more = animation.getTransformation(
9278 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009279 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 TAG, "Stepped animation in " + this +
9281 ": more=" + more + ", xform=" + transformation);
9282 if (more) {
9283 // we're done!
9284 hasTransformation = true;
9285 return true;
9286 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009287 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009288 TAG, "Finished animation in " + this +
9289 " @ " + currentTime);
9290 animation = null;
9291 }
9292 } else if (animation != null) {
9293 // If the display is frozen, and there is a pending animation,
9294 // clear it and make sure we run the cleanup code.
9295 animating = true;
9296 animation = null;
9297 }
9298
9299 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07009300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009301 if (!animating) {
9302 return false;
9303 }
9304
9305 clearAnimation();
9306 animating = false;
9307 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
9308 moveInputMethodWindowsIfNeededLocked(true);
9309 }
Romain Guy06882f82009-06-10 13:36:04 -07009310
Joe Onorato8a9b2202010-02-26 18:56:32 -08009311 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009312 TAG, "Animation done in " + this
9313 + ": reportedVisible=" + reportedVisible);
9314
9315 transformation.clear();
9316 if (animLayerAdjustment != 0) {
9317 animLayerAdjustment = 0;
9318 updateLayers();
9319 }
Romain Guy06882f82009-06-10 13:36:04 -07009320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 final int N = windows.size();
9322 for (int i=0; i<N; i++) {
9323 ((WindowState)windows.get(i)).finishExit();
9324 }
9325 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07009326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327 return false;
9328 }
9329
9330 void updateReportedVisibilityLocked() {
9331 if (appToken == null) {
9332 return;
9333 }
Romain Guy06882f82009-06-10 13:36:04 -07009334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009335 int numInteresting = 0;
9336 int numVisible = 0;
9337 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07009338
Joe Onorato8a9b2202010-02-26 18:56:32 -08009339 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 final int N = allAppWindows.size();
9341 for (int i=0; i<N; i++) {
9342 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08009343 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07009344 || win.mViewVisibility != View.VISIBLE
9345 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 continue;
9347 }
9348 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009349 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009350 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009352 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009353 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009354 + " pv=" + win.mPolicyVisibility
9355 + " dp=" + win.mDrawPending
9356 + " cdp=" + win.mCommitDrawPending
9357 + " ah=" + win.mAttachedHidden
9358 + " th="
9359 + (win.mAppToken != null
9360 ? win.mAppToken.hiddenRequested : false)
9361 + " a=" + win.mAnimating);
9362 }
9363 }
9364 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009365 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009366 if (!win.isAnimating()) {
9367 numVisible++;
9368 }
9369 nowGone = false;
9370 } else if (win.isAnimating()) {
9371 nowGone = false;
9372 }
9373 }
Romain Guy06882f82009-06-10 13:36:04 -07009374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009375 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009376 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377 + numInteresting + " visible=" + numVisible);
9378 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009379 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 TAG, "Visibility changed in " + this
9381 + ": vis=" + nowVisible);
9382 reportedVisible = nowVisible;
9383 Message m = mH.obtainMessage(
9384 H.REPORT_APPLICATION_TOKEN_WINDOWS,
9385 nowVisible ? 1 : 0,
9386 nowGone ? 1 : 0,
9387 this);
9388 mH.sendMessage(m);
9389 }
9390 }
Romain Guy06882f82009-06-10 13:36:04 -07009391
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009392 WindowState findMainWindow() {
9393 int j = windows.size();
9394 while (j > 0) {
9395 j--;
9396 WindowState win = windows.get(j);
9397 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
9398 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
9399 return win;
9400 }
9401 }
9402 return null;
9403 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009405 void dump(PrintWriter pw, String prefix) {
9406 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009407 if (appToken != null) {
9408 pw.print(prefix); pw.println("app=true");
9409 }
9410 if (allAppWindows.size() > 0) {
9411 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
9412 }
9413 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009414 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009415 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
9416 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
9417 pw.print(" clientHidden="); pw.print(clientHidden);
9418 pw.print(" willBeHidden="); pw.print(willBeHidden);
9419 pw.print(" reportedVisible="); pw.println(reportedVisible);
9420 if (paused || freezingScreen) {
9421 pw.print(prefix); pw.print("paused="); pw.print(paused);
9422 pw.print(" freezingScreen="); pw.println(freezingScreen);
9423 }
9424 if (numInterestingWindows != 0 || numDrawnWindows != 0
9425 || inPendingTransaction || allDrawn) {
9426 pw.print(prefix); pw.print("numInterestingWindows=");
9427 pw.print(numInterestingWindows);
9428 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
9429 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
9430 pw.print(" allDrawn="); pw.println(allDrawn);
9431 }
9432 if (animating || animation != null) {
9433 pw.print(prefix); pw.print("animating="); pw.print(animating);
9434 pw.print(" animation="); pw.println(animation);
9435 }
9436 if (animLayerAdjustment != 0) {
9437 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
9438 }
9439 if (hasTransformation) {
9440 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
9441 pw.print(" transformation="); transformation.printShortString(pw);
9442 pw.println();
9443 }
9444 if (startingData != null || removed || firstWindowDrawn) {
9445 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
9446 pw.print(" removed="); pw.print(removed);
9447 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
9448 }
9449 if (startingWindow != null || startingView != null
9450 || startingDisplayed || startingMoved) {
9451 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
9452 pw.print(" startingView="); pw.print(startingView);
9453 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
9454 pw.print(" startingMoved"); pw.println(startingMoved);
9455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 }
9457
9458 @Override
9459 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009460 if (stringName == null) {
9461 StringBuilder sb = new StringBuilder();
9462 sb.append("AppWindowToken{");
9463 sb.append(Integer.toHexString(System.identityHashCode(this)));
9464 sb.append(" token="); sb.append(token); sb.append('}');
9465 stringName = sb.toString();
9466 }
9467 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009468 }
9469 }
Romain Guy06882f82009-06-10 13:36:04 -07009470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471 // -------------------------------------------------------------
9472 // DummyAnimation
9473 // -------------------------------------------------------------
9474
9475 // This is an animation that does nothing: it just immediately finishes
9476 // itself every time it is called. It is used as a stub animation in cases
9477 // where we want to synchronize multiple things that may be animating.
9478 static final class DummyAnimation extends Animation {
9479 public boolean getTransformation(long currentTime, Transformation outTransformation) {
9480 return false;
9481 }
9482 }
9483 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07009484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009485 // -------------------------------------------------------------
9486 // Async Handler
9487 // -------------------------------------------------------------
9488
9489 static final class StartingData {
9490 final String pkg;
9491 final int theme;
9492 final CharSequence nonLocalizedLabel;
9493 final int labelRes;
9494 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07009495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009496 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
9497 int _labelRes, int _icon) {
9498 pkg = _pkg;
9499 theme = _theme;
9500 nonLocalizedLabel = _nonLocalizedLabel;
9501 labelRes = _labelRes;
9502 icon = _icon;
9503 }
9504 }
9505
9506 private final class H extends Handler {
9507 public static final int REPORT_FOCUS_CHANGE = 2;
9508 public static final int REPORT_LOSING_FOCUS = 3;
9509 public static final int ANIMATE = 4;
9510 public static final int ADD_STARTING = 5;
9511 public static final int REMOVE_STARTING = 6;
9512 public static final int FINISHED_STARTING = 7;
9513 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 public static final int WINDOW_FREEZE_TIMEOUT = 11;
9515 public static final int HOLD_SCREEN_CHANGED = 12;
9516 public static final int APP_TRANSITION_TIMEOUT = 13;
9517 public static final int PERSIST_ANIMATION_SCALE = 14;
9518 public static final int FORCE_GC = 15;
9519 public static final int ENABLE_SCREEN = 16;
9520 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009521 public static final int SEND_NEW_CONFIGURATION = 18;
Romain Guy06882f82009-06-10 13:36:04 -07009522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07009524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 public H() {
9526 }
Romain Guy06882f82009-06-10 13:36:04 -07009527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009528 @Override
9529 public void handleMessage(Message msg) {
9530 switch (msg.what) {
9531 case REPORT_FOCUS_CHANGE: {
9532 WindowState lastFocus;
9533 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07009534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 synchronized(mWindowMap) {
9536 lastFocus = mLastFocus;
9537 newFocus = mCurrentFocus;
9538 if (lastFocus == newFocus) {
9539 // Focus is not changing, so nothing to do.
9540 return;
9541 }
9542 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009543 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009544 // + " to " + newFocus);
9545 if (newFocus != null && lastFocus != null
9546 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009547 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 mLosingFocus.add(lastFocus);
9549 lastFocus = null;
9550 }
9551 }
9552
9553 if (lastFocus != newFocus) {
9554 //System.out.println("Changing focus from " + lastFocus
9555 // + " to " + newFocus);
9556 if (newFocus != null) {
9557 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009558 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
9560 } catch (RemoteException e) {
9561 // Ignore if process has died.
9562 }
9563 }
9564
9565 if (lastFocus != null) {
9566 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009567 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009568 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
9569 } catch (RemoteException e) {
9570 // Ignore if process has died.
9571 }
9572 }
9573 }
9574 } break;
9575
9576 case REPORT_LOSING_FOCUS: {
9577 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07009578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009579 synchronized(mWindowMap) {
9580 losers = mLosingFocus;
9581 mLosingFocus = new ArrayList<WindowState>();
9582 }
9583
9584 final int N = losers.size();
9585 for (int i=0; i<N; i++) {
9586 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009587 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009588 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
9589 } catch (RemoteException e) {
9590 // Ignore if process has died.
9591 }
9592 }
9593 } break;
9594
9595 case ANIMATE: {
9596 synchronized(mWindowMap) {
9597 mAnimationPending = false;
9598 performLayoutAndPlaceSurfacesLocked();
9599 }
9600 } break;
9601
9602 case ADD_STARTING: {
9603 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9604 final StartingData sd = wtoken.startingData;
9605
9606 if (sd == null) {
9607 // Animation has been canceled... do nothing.
9608 return;
9609 }
Romain Guy06882f82009-06-10 13:36:04 -07009610
Joe Onorato8a9b2202010-02-26 18:56:32 -08009611 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009612 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07009613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009614 View view = null;
9615 try {
9616 view = mPolicy.addStartingWindow(
9617 wtoken.token, sd.pkg,
9618 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
9619 sd.icon);
9620 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009621 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009622 }
9623
9624 if (view != null) {
9625 boolean abort = false;
9626
9627 synchronized(mWindowMap) {
9628 if (wtoken.removed || wtoken.startingData == null) {
9629 // If the window was successfully added, then
9630 // we need to remove it.
9631 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009632 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633 "Aborted starting " + wtoken
9634 + ": removed=" + wtoken.removed
9635 + " startingData=" + wtoken.startingData);
9636 wtoken.startingWindow = null;
9637 wtoken.startingData = null;
9638 abort = true;
9639 }
9640 } else {
9641 wtoken.startingView = view;
9642 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009643 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 "Added starting " + wtoken
9645 + ": startingWindow="
9646 + wtoken.startingWindow + " startingView="
9647 + wtoken.startingView);
9648 }
9649
9650 if (abort) {
9651 try {
9652 mPolicy.removeStartingWindow(wtoken.token, view);
9653 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009654 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009655 }
9656 }
9657 }
9658 } break;
9659
9660 case REMOVE_STARTING: {
9661 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9662 IBinder token = null;
9663 View view = null;
9664 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009665 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009666 + wtoken + ": startingWindow="
9667 + wtoken.startingWindow + " startingView="
9668 + wtoken.startingView);
9669 if (wtoken.startingWindow != null) {
9670 view = wtoken.startingView;
9671 token = wtoken.token;
9672 wtoken.startingData = null;
9673 wtoken.startingView = null;
9674 wtoken.startingWindow = null;
9675 }
9676 }
9677 if (view != null) {
9678 try {
9679 mPolicy.removeStartingWindow(token, view);
9680 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009681 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009682 }
9683 }
9684 } break;
9685
9686 case FINISHED_STARTING: {
9687 IBinder token = null;
9688 View view = null;
9689 while (true) {
9690 synchronized (mWindowMap) {
9691 final int N = mFinishedStarting.size();
9692 if (N <= 0) {
9693 break;
9694 }
9695 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9696
Joe Onorato8a9b2202010-02-26 18:56:32 -08009697 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 "Finished starting " + wtoken
9699 + ": startingWindow=" + wtoken.startingWindow
9700 + " startingView=" + wtoken.startingView);
9701
9702 if (wtoken.startingWindow == null) {
9703 continue;
9704 }
9705
9706 view = wtoken.startingView;
9707 token = wtoken.token;
9708 wtoken.startingData = null;
9709 wtoken.startingView = null;
9710 wtoken.startingWindow = null;
9711 }
9712
9713 try {
9714 mPolicy.removeStartingWindow(token, view);
9715 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009716 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009717 }
9718 }
9719 } break;
9720
9721 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9722 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9723
9724 boolean nowVisible = msg.arg1 != 0;
9725 boolean nowGone = msg.arg2 != 0;
9726
9727 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009728 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009729 TAG, "Reporting visible in " + wtoken
9730 + " visible=" + nowVisible
9731 + " gone=" + nowGone);
9732 if (nowVisible) {
9733 wtoken.appToken.windowsVisible();
9734 } else {
9735 wtoken.appToken.windowsGone();
9736 }
9737 } catch (RemoteException ex) {
9738 }
9739 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 case WINDOW_FREEZE_TIMEOUT: {
9742 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009743 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 int i = mWindows.size();
9745 while (i > 0) {
9746 i--;
9747 WindowState w = (WindowState)mWindows.get(i);
9748 if (w.mOrientationChanging) {
9749 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009750 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009751 }
9752 }
9753 performLayoutAndPlaceSurfacesLocked();
9754 }
9755 break;
9756 }
Romain Guy06882f82009-06-10 13:36:04 -07009757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 case HOLD_SCREEN_CHANGED: {
9759 Session oldHold;
9760 Session newHold;
9761 synchronized (mWindowMap) {
9762 oldHold = mLastReportedHold;
9763 newHold = (Session)msg.obj;
9764 mLastReportedHold = newHold;
9765 }
Romain Guy06882f82009-06-10 13:36:04 -07009766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 if (oldHold != newHold) {
9768 try {
9769 if (oldHold != null) {
9770 mBatteryStats.noteStopWakelock(oldHold.mUid,
9771 "window",
9772 BatteryStats.WAKE_TYPE_WINDOW);
9773 }
9774 if (newHold != null) {
9775 mBatteryStats.noteStartWakelock(newHold.mUid,
9776 "window",
9777 BatteryStats.WAKE_TYPE_WINDOW);
9778 }
9779 } catch (RemoteException e) {
9780 }
9781 }
9782 break;
9783 }
Romain Guy06882f82009-06-10 13:36:04 -07009784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009785 case APP_TRANSITION_TIMEOUT: {
9786 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009787 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009788 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009789 "*** APP TRANSITION TIMEOUT");
9790 mAppTransitionReady = true;
9791 mAppTransitionTimeout = true;
9792 performLayoutAndPlaceSurfacesLocked();
9793 }
9794 }
9795 break;
9796 }
Romain Guy06882f82009-06-10 13:36:04 -07009797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 case PERSIST_ANIMATION_SCALE: {
9799 Settings.System.putFloat(mContext.getContentResolver(),
9800 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9801 Settings.System.putFloat(mContext.getContentResolver(),
9802 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9803 break;
9804 }
Romain Guy06882f82009-06-10 13:36:04 -07009805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806 case FORCE_GC: {
9807 synchronized(mWindowMap) {
9808 if (mAnimationPending) {
9809 // If we are animating, don't do the gc now but
9810 // delay a bit so we don't interrupt the animation.
9811 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9812 2000);
9813 return;
9814 }
9815 // If we are currently rotating the display, it will
9816 // schedule a new message when done.
9817 if (mDisplayFrozen) {
9818 return;
9819 }
9820 mFreezeGcPending = 0;
9821 }
9822 Runtime.getRuntime().gc();
9823 break;
9824 }
Romain Guy06882f82009-06-10 13:36:04 -07009825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 case ENABLE_SCREEN: {
9827 performEnableScreen();
9828 break;
9829 }
Romain Guy06882f82009-06-10 13:36:04 -07009830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 case APP_FREEZE_TIMEOUT: {
9832 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009833 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009834 int i = mAppTokens.size();
9835 while (i > 0) {
9836 i--;
9837 AppWindowToken tok = mAppTokens.get(i);
9838 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009839 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 unsetAppFreezingScreenLocked(tok, true, true);
9841 }
9842 }
9843 }
9844 break;
9845 }
Romain Guy06882f82009-06-10 13:36:04 -07009846
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009847 case SEND_NEW_CONFIGURATION: {
9848 removeMessages(SEND_NEW_CONFIGURATION);
9849 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009850 break;
9851 }
Romain Guy06882f82009-06-10 13:36:04 -07009852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 }
9854 }
9855 }
9856
9857 // -------------------------------------------------------------
9858 // IWindowManager API
9859 // -------------------------------------------------------------
9860
9861 public IWindowSession openSession(IInputMethodClient client,
9862 IInputContext inputContext) {
9863 if (client == null) throw new IllegalArgumentException("null client");
9864 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009865 Session session = new Session(client, inputContext);
9866 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009867 }
9868
9869 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9870 synchronized (mWindowMap) {
9871 // The focus for the client is the window immediately below
9872 // where we would place the input method window.
9873 int idx = findDesiredInputMethodWindowIndexLocked(false);
9874 WindowState imFocus;
9875 if (idx > 0) {
9876 imFocus = (WindowState)mWindows.get(idx-1);
9877 if (imFocus != null) {
9878 if (imFocus.mSession.mClient != null &&
9879 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9880 return true;
9881 }
9882 }
9883 }
9884 }
9885 return false;
9886 }
Romain Guy06882f82009-06-10 13:36:04 -07009887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 // -------------------------------------------------------------
9889 // Internals
9890 // -------------------------------------------------------------
9891
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009892 final WindowState windowForClientLocked(Session session, IWindow client,
9893 boolean throwOnError) {
9894 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 }
Romain Guy06882f82009-06-10 13:36:04 -07009896
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009897 final WindowState windowForClientLocked(Session session, IBinder client,
9898 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009899 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009900 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 TAG, "Looking up client " + client + ": " + win);
9902 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009903 RuntimeException ex = new IllegalArgumentException(
9904 "Requested window " + client + " does not exist");
9905 if (throwOnError) {
9906 throw ex;
9907 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009908 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 return null;
9910 }
9911 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009912 RuntimeException ex = new IllegalArgumentException(
9913 "Requested window " + client + " is in session " +
9914 win.mSession + ", not " + session);
9915 if (throwOnError) {
9916 throw ex;
9917 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009918 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009919 return null;
9920 }
9921
9922 return win;
9923 }
9924
Dianne Hackborna8f60182009-09-01 19:01:50 -07009925 final void rebuildAppWindowListLocked() {
9926 int NW = mWindows.size();
9927 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009928 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009929 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009930
Dianne Hackborna8f60182009-09-01 19:01:50 -07009931 // First remove all existing app windows.
9932 i=0;
9933 while (i < NW) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009934 WindowState w = (WindowState)mWindows.get(i);
9935 if (w.mAppToken != null) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009936 WindowState win = (WindowState)mWindows.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009937 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009938 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009939 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009940 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009941 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009942 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9943 && lastWallpaper == i-1) {
9944 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009945 }
9946 i++;
9947 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009948
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009949 // The wallpaper window(s) typically live at the bottom of the stack,
9950 // so skip them before adding app tokens.
9951 lastWallpaper++;
9952 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009953
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009954 // First add all of the exiting app tokens... these are no longer
9955 // in the main app list, but still have windows shown. We put them
9956 // in the back because now that the animation is over we no longer
9957 // will care about them.
9958 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009959 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009960 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9961 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009962
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009963 // And add in the still active app tokens in Z order.
9964 NT = mAppTokens.size();
9965 for (int j=0; j<NT; j++) {
9966 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009967 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009968
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009969 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009970 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009971 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009972 + " windows but added " + i);
9973 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009974 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976 private final void assignLayersLocked() {
9977 int N = mWindows.size();
9978 int curBaseLayer = 0;
9979 int curLayer = 0;
9980 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009982 for (i=0; i<N; i++) {
9983 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009984 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9985 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009986 curLayer += WINDOW_LAYER_MULTIPLIER;
9987 w.mLayer = curLayer;
9988 } else {
9989 curBaseLayer = curLayer = w.mBaseLayer;
9990 w.mLayer = curLayer;
9991 }
9992 if (w.mTargetAppToken != null) {
9993 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9994 } else if (w.mAppToken != null) {
9995 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9996 } else {
9997 w.mAnimLayer = w.mLayer;
9998 }
9999 if (w.mIsImWindow) {
10000 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070010001 } else if (w.mIsWallpaper) {
10002 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010004 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 + w.mAnimLayer);
10006 //System.out.println(
10007 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
10008 }
10009 }
10010
10011 private boolean mInLayout = false;
10012 private final void performLayoutAndPlaceSurfacesLocked() {
10013 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -070010014 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 throw new RuntimeException("Recursive call!");
10016 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010017 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 return;
10019 }
10020
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010021 if (mWaitingForConfig) {
10022 // Our configuration has changed (most likely rotation), but we
10023 // don't yet have the complete configuration to report to
10024 // applications. Don't do any window layout until we have it.
10025 return;
10026 }
10027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028 boolean recoveringMemory = false;
10029 if (mForceRemoves != null) {
10030 recoveringMemory = true;
10031 // Wait a little it for things to settle down, and off we go.
10032 for (int i=0; i<mForceRemoves.size(); i++) {
10033 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010034 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010035 removeWindowInnerLocked(ws.mSession, ws);
10036 }
10037 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010038 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 Object tmp = new Object();
10040 synchronized (tmp) {
10041 try {
10042 tmp.wait(250);
10043 } catch (InterruptedException e) {
10044 }
10045 }
10046 }
Romain Guy06882f82009-06-10 13:36:04 -070010047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 mInLayout = true;
10049 try {
10050 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -070010051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 int i = mPendingRemove.size()-1;
10053 if (i >= 0) {
10054 while (i >= 0) {
10055 WindowState w = mPendingRemove.get(i);
10056 removeWindowInnerLocked(w.mSession, w);
10057 i--;
10058 }
10059 mPendingRemove.clear();
10060
10061 mInLayout = false;
10062 assignLayersLocked();
10063 mLayoutNeeded = true;
10064 performLayoutAndPlaceSurfacesLocked();
10065
10066 } else {
10067 mInLayout = false;
10068 if (mLayoutNeeded) {
10069 requestAnimationLocked(0);
10070 }
10071 }
10072 } catch (RuntimeException e) {
10073 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010074 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010075 }
10076 }
10077
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010078 private final int performLayoutLockedInner() {
10079 if (!mLayoutNeeded) {
10080 return 0;
10081 }
10082
10083 mLayoutNeeded = false;
10084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085 final int dw = mDisplay.getWidth();
10086 final int dh = mDisplay.getHeight();
10087
10088 final int N = mWindows.size();
10089 int i;
10090
Joe Onorato8a9b2202010-02-26 18:56:32 -080010091 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -080010092 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
10093
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010094 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -070010095
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010096 int seq = mLayoutSeq+1;
10097 if (seq < 0) seq = 0;
10098 mLayoutSeq = seq;
10099
10100 // First perform layout of any root windows (not attached
10101 // to another window).
10102 int topAttached = -1;
10103 for (i = N-1; i >= 0; i--) {
10104 WindowState win = (WindowState) mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010106 // Don't do layout of a window if it is not visible, or
10107 // soon won't be visible, to avoid wasting time and funky
10108 // changes while a window is animating away.
10109 final AppWindowToken atoken = win.mAppToken;
10110 final boolean gone = win.mViewVisibility == View.GONE
10111 || !win.mRelayoutCalled
10112 || win.mRootToken.hidden
10113 || (atoken != null && atoken.hiddenRequested)
10114 || win.mAttachedHidden
10115 || win.mExiting || win.mDestroying;
10116
10117 if (!win.mLayoutAttached) {
10118 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
10119 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
10120 + " mLayoutAttached=" + win.mLayoutAttached);
10121 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
10122 + win.mViewVisibility + " mRelayoutCalled="
10123 + win.mRelayoutCalled + " hidden="
10124 + win.mRootToken.hidden + " hiddenRequested="
10125 + (atoken != null && atoken.hiddenRequested)
10126 + " mAttachedHidden=" + win.mAttachedHidden);
10127 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010128
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010129 // If this view is GONE, then skip it -- keep the current
10130 // frame, and let the caller know so they can ignore it
10131 // if they want. (We do the normal layout for INVISIBLE
10132 // windows, since that means "perform layout as normal,
10133 // just don't display").
10134 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010135 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010136 mPolicy.layoutWindowLw(win, win.mAttrs, null);
10137 win.mLayoutSeq = seq;
10138 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
10139 + win.mFrame + " mContainingFrame="
10140 + win.mContainingFrame + " mDisplayFrame="
10141 + win.mDisplayFrame);
10142 } else {
10143 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010144 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -070010145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010147
10148 // Now perform layout of attached windows, which usually
10149 // depend on the position of the window they are attached to.
10150 // XXX does not deal with windows that are attached to windows
10151 // that are themselves attached.
10152 for (i = topAttached; i >= 0; i--) {
10153 WindowState win = (WindowState) mWindows.get(i);
10154
10155 // If this view is GONE, then skip it -- keep the current
10156 // frame, and let the caller know so they can ignore it
10157 // if they want. (We do the normal layout for INVISIBLE
10158 // windows, since that means "perform layout as normal,
10159 // just don't display").
10160 if (win.mLayoutAttached) {
10161 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
10162 + " mHaveFrame=" + win.mHaveFrame
10163 + " mViewVisibility=" + win.mViewVisibility
10164 + " mRelayoutCalled=" + win.mRelayoutCalled);
10165 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
10166 || !win.mHaveFrame) {
10167 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
10168 win.mLayoutSeq = seq;
10169 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
10170 + win.mFrame + " mContainingFrame="
10171 + win.mContainingFrame + " mDisplayFrame="
10172 + win.mDisplayFrame);
10173 }
10174 }
10175 }
Jeff Brown349703e2010-06-22 01:27:15 -070010176
10177 // Window frames may have changed. Tell the input dispatcher about it.
10178 if (ENABLE_NATIVE_INPUT_DISPATCH) {
10179 mInputMonitor.updateInputWindowsLw();
10180 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010181
10182 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183 }
Romain Guy06882f82009-06-10 13:36:04 -070010184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 private final void performLayoutAndPlaceSurfacesLockedInner(
10186 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -040010187 if (mDisplay == null) {
10188 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
10189 return;
10190 }
10191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010192 final long currentTime = SystemClock.uptimeMillis();
10193 final int dw = mDisplay.getWidth();
10194 final int dh = mDisplay.getHeight();
10195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 int i;
10197
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010198 if (mFocusMayChange) {
10199 mFocusMayChange = false;
10200 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
10201 }
10202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010203 if (mFxSession == null) {
10204 mFxSession = new SurfaceSession();
10205 }
Romain Guy06882f82009-06-10 13:36:04 -070010206
Joe Onorato8a9b2202010-02-26 18:56:32 -080010207 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208
10209 // Initialize state of exiting tokens.
10210 for (i=mExitingTokens.size()-1; i>=0; i--) {
10211 mExitingTokens.get(i).hasVisible = false;
10212 }
10213
10214 // Initialize state of exiting applications.
10215 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10216 mExitingAppTokens.get(i).hasVisible = false;
10217 }
10218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 boolean orientationChangeComplete = true;
10220 Session holdScreen = null;
10221 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010222 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 boolean focusDisplayed = false;
10224 boolean animating = false;
10225
10226 Surface.openTransaction();
10227 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010228 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010229 int repeats = 0;
10230 int changes = 0;
10231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010232 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010233 repeats++;
10234 if (repeats > 6) {
10235 Slog.w(TAG, "Animation repeat aborted after too many iterations");
10236 mLayoutNeeded = false;
10237 break;
10238 }
10239
10240 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
10241 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
10242 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
10243 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
10244 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
10245 assignLayersLocked();
10246 mLayoutNeeded = true;
10247 }
10248 }
10249 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
10250 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
10251 if (updateOrientationFromAppTokensLocked()) {
10252 mLayoutNeeded = true;
10253 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10254 }
10255 }
10256 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
10257 mLayoutNeeded = true;
10258 }
10259 }
10260
10261 // FIRST LOOP: Perform a layout, if needed.
10262 if (repeats < 4) {
10263 changes = performLayoutLockedInner();
10264 if (changes != 0) {
10265 continue;
10266 }
10267 } else {
10268 Slog.w(TAG, "Layout repeat skipped after too many iterations");
10269 changes = 0;
10270 }
10271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010272 final int transactionSequence = ++mTransactionSequence;
10273
10274 // Update animations of all applications, including those
10275 // associated with exiting/removed apps
10276 boolean tokensAnimating = false;
10277 final int NAT = mAppTokens.size();
10278 for (i=0; i<NAT; i++) {
10279 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10280 tokensAnimating = true;
10281 }
10282 }
10283 final int NEAT = mExitingAppTokens.size();
10284 for (i=0; i<NEAT; i++) {
10285 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
10286 tokensAnimating = true;
10287 }
10288 }
10289
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010290 // SECOND LOOP: Execute animations and update visibility of windows.
10291
Joe Onorato8a9b2202010-02-26 18:56:32 -080010292 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010293 + transactionSequence + " tokensAnimating="
10294 + tokensAnimating);
10295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297
10298 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010299 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010300 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301
10302 mPolicy.beginAnimationLw(dw, dh);
10303
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010304 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010306 for (i=N-1; i>=0; i--) {
10307 WindowState w = (WindowState)mWindows.get(i);
10308
10309 final WindowManager.LayoutParams attrs = w.mAttrs;
10310
10311 if (w.mSurface != null) {
10312 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010313 if (w.commitFinishDrawingLocked(currentTime)) {
10314 if ((w.mAttrs.flags
10315 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010316 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010317 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010318 wallpaperMayChange = true;
10319 }
10320 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010321
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010322 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 if (w.stepAnimationLocked(currentTime, dw, dh)) {
10324 animating = true;
10325 //w.dump(" ");
10326 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -070010327 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
10328 wallpaperMayChange = true;
10329 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010330
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010331 if (mPolicy.doesForceHide(w, attrs)) {
10332 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010333 if (DEBUG_VISIBILITY) Slog.v(TAG,
10334 "Animation done that could impact force hide: "
10335 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010336 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010337 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010338 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
10339 forceHiding = true;
10340 }
10341 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10342 boolean changed;
10343 if (forceHiding) {
10344 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010345 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10346 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010347 } else {
10348 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010349 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
10350 "Now policy shown: " + w);
10351 if (changed) {
10352 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010353 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010354 // Assume we will need to animate. If
10355 // we don't (because the wallpaper will
10356 // stay with the lock screen), then we will
10357 // clean up later.
10358 Animation a = mPolicy.createForceHideEnterAnimation();
10359 if (a != null) {
10360 w.setAnimation(a);
10361 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010362 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080010363 if (mCurrentFocus == null ||
10364 mCurrentFocus.mLayer < w.mLayer) {
10365 // We are showing on to of the current
10366 // focus, so re-evaluate focus to make
10367 // sure it is correct.
10368 mFocusMayChange = true;
10369 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010370 }
10371 }
10372 if (changed && (attrs.flags
10373 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
10374 wallpaperMayChange = true;
10375 }
10376 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 mPolicy.animatingWindowLw(w, attrs);
10379 }
10380
10381 final AppWindowToken atoken = w.mAppToken;
10382 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
10383 if (atoken.lastTransactionSequence != transactionSequence) {
10384 atoken.lastTransactionSequence = transactionSequence;
10385 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
10386 atoken.startingDisplayed = false;
10387 }
10388 if ((w.isOnScreen() || w.mAttrs.type
10389 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
10390 && !w.mExiting && !w.mDestroying) {
10391 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010392 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010393 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010394 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010395 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010396 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 + " pv=" + w.mPolicyVisibility
10398 + " dp=" + w.mDrawPending
10399 + " cdp=" + w.mCommitDrawPending
10400 + " ah=" + w.mAttachedHidden
10401 + " th=" + atoken.hiddenRequested
10402 + " a=" + w.mAnimating);
10403 }
10404 }
10405 if (w != atoken.startingWindow) {
10406 if (!atoken.freezingScreen || !w.mAppFreezing) {
10407 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010408 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010409 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010410 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 "tokenMayBeDrawn: " + atoken
10412 + " freezingScreen=" + atoken.freezingScreen
10413 + " mAppFreezing=" + w.mAppFreezing);
10414 tokenMayBeDrawn = true;
10415 }
10416 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010417 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 atoken.startingDisplayed = true;
10419 }
10420 }
10421 } else if (w.mReadyToShow) {
10422 w.performShowLocked();
10423 }
10424 }
10425
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010426 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427
10428 if (tokenMayBeDrawn) {
10429 // See if any windows have been drawn, so they (and others
10430 // associated with them) can now be shown.
10431 final int NT = mTokenList.size();
10432 for (i=0; i<NT; i++) {
10433 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
10434 if (wtoken == null) {
10435 continue;
10436 }
10437 if (wtoken.freezingScreen) {
10438 int numInteresting = wtoken.numInterestingWindows;
10439 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010440 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010441 "allDrawn: " + wtoken
10442 + " interesting=" + numInteresting
10443 + " drawn=" + wtoken.numDrawnWindows);
10444 wtoken.showAllWindowsLocked();
10445 unsetAppFreezingScreenLocked(wtoken, false, true);
10446 orientationChangeComplete = true;
10447 }
10448 } else if (!wtoken.allDrawn) {
10449 int numInteresting = wtoken.numInterestingWindows;
10450 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 "allDrawn: " + wtoken
10453 + " interesting=" + numInteresting
10454 + " drawn=" + wtoken.numDrawnWindows);
10455 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010456 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457
10458 // We can now show all of the drawn windows!
10459 if (!mOpeningApps.contains(wtoken)) {
10460 wtoken.showAllWindowsLocked();
10461 }
10462 }
10463 }
10464 }
10465 }
10466
10467 // If we are ready to perform an app transition, check through
10468 // all of the app tokens to be shown and see if they are ready
10469 // to go.
10470 if (mAppTransitionReady) {
10471 int NN = mOpeningApps.size();
10472 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010473 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 "Checking " + NN + " opening apps (frozen="
10475 + mDisplayFrozen + " timeout="
10476 + mAppTransitionTimeout + ")...");
10477 if (!mDisplayFrozen && !mAppTransitionTimeout) {
10478 // If the display isn't frozen, wait to do anything until
10479 // all of the apps are ready. Otherwise just go because
10480 // we'll unfreeze the display when everyone is ready.
10481 for (i=0; i<NN && goodToGo; i++) {
10482 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010483 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 "Check opening app" + wtoken + ": allDrawn="
10485 + wtoken.allDrawn + " startingDisplayed="
10486 + wtoken.startingDisplayed);
10487 if (!wtoken.allDrawn && !wtoken.startingDisplayed
10488 && !wtoken.startingMoved) {
10489 goodToGo = false;
10490 }
10491 }
10492 }
10493 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010494 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 int transit = mNextAppTransition;
10496 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010497 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010498 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010499 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010501 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010502 mAppTransitionTimeout = false;
10503 mStartingIconInTransition = false;
10504 mSkipAppTransitionAnimation = false;
10505
10506 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
10507
Dianne Hackborna8f60182009-09-01 19:01:50 -070010508 // If there are applications waiting to come to the
10509 // top of the stack, now is the time to move their windows.
10510 // (Note that we don't do apps going to the bottom
10511 // here -- we want to keep their windows in the old
10512 // Z-order until the animation completes.)
10513 if (mToTopApps.size() > 0) {
10514 NN = mAppTokens.size();
10515 for (i=0; i<NN; i++) {
10516 AppWindowToken wtoken = mAppTokens.get(i);
10517 if (wtoken.sendingToTop) {
10518 wtoken.sendingToTop = false;
10519 moveAppWindowsLocked(wtoken, NN, false);
10520 }
10521 }
10522 mToTopApps.clear();
10523 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010524
Dianne Hackborn25994b42009-09-04 14:21:19 -070010525 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010526
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010527 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010528 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010529
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010530 // The top-most window will supply the layout params,
10531 // and we will determine it below.
10532 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010533 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010534 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010535
Joe Onorato8a9b2202010-02-26 18:56:32 -080010536 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010537 "New wallpaper target=" + mWallpaperTarget
10538 + ", lower target=" + mLowerWallpaperTarget
10539 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -070010540 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010541 // Do a first pass through the tokens for two
10542 // things:
10543 // (1) Determine if both the closing and opening
10544 // app token sets are wallpaper targets, in which
10545 // case special animations are needed
10546 // (since the wallpaper needs to stay static
10547 // behind them).
10548 // (2) Find the layout params of the top-most
10549 // application window in the tokens, which is
10550 // what will control the animation theme.
10551 final int NC = mClosingApps.size();
10552 NN = NC + mOpeningApps.size();
10553 for (i=0; i<NN; i++) {
10554 AppWindowToken wtoken;
10555 int mode;
10556 if (i < NC) {
10557 wtoken = mClosingApps.get(i);
10558 mode = 1;
10559 } else {
10560 wtoken = mOpeningApps.get(i-NC);
10561 mode = 2;
10562 }
10563 if (mLowerWallpaperTarget != null) {
10564 if (mLowerWallpaperTarget.mAppToken == wtoken
10565 || mUpperWallpaperTarget.mAppToken == wtoken) {
10566 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010567 }
10568 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010569 if (wtoken.appFullscreen) {
10570 WindowState ws = wtoken.findMainWindow();
10571 if (ws != null) {
10572 // If this is a compatibility mode
10573 // window, we will always use its anim.
10574 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
10575 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010576 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010577 bestAnimLayer = Integer.MAX_VALUE;
10578 } else if (ws.mLayer > bestAnimLayer) {
10579 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010580 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010581 bestAnimLayer = ws.mLayer;
10582 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010583 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010584 }
10585 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010586
Dianne Hackborn25994b42009-09-04 14:21:19 -070010587 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010588 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010589 "Wallpaper animation!");
10590 switch (transit) {
10591 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10592 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10593 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10594 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10595 break;
10596 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10597 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10598 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10599 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10600 break;
10601 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010602 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010603 "New transit: " + transit);
10604 } else if (oldWallpaper != null) {
10605 // We are transitioning from an activity with
10606 // a wallpaper to one without.
10607 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010608 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010609 "New transit away from wallpaper: " + transit);
10610 } else if (mWallpaperTarget != null) {
10611 // We are transitioning from an activity without
10612 // a wallpaper to now showing the wallpaper
10613 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010614 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010615 "New transit into wallpaper: " + transit);
10616 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010617
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010618 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
10619 mLastEnterAnimToken = animToken;
10620 mLastEnterAnimParams = animLp;
10621 } else if (mLastEnterAnimParams != null) {
10622 animLp = mLastEnterAnimParams;
10623 mLastEnterAnimToken = null;
10624 mLastEnterAnimParams = null;
10625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010626
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010627 // If all closing windows are obscured, then there is
10628 // no need to do an animation. This is the case, for
10629 // example, when this transition is being done behind
10630 // the lock screen.
10631 if (!mPolicy.allowAppAnimationsLw()) {
10632 animLp = null;
10633 }
10634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010635 NN = mOpeningApps.size();
10636 for (i=0; i<NN; i++) {
10637 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010638 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010639 "Now opening app" + wtoken);
10640 wtoken.reportedVisible = false;
10641 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010642 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010643 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010645 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 wtoken.showAllWindowsLocked();
10647 }
10648 NN = mClosingApps.size();
10649 for (i=0; i<NN; i++) {
10650 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010651 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 "Now closing app" + wtoken);
10653 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010654 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010655 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010657 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010658 // Force the allDrawn flag, because we want to start
10659 // this guy's animations regardless of whether it's
10660 // gotten drawn.
10661 wtoken.allDrawn = true;
10662 }
10663
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010664 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010666 mOpeningApps.clear();
10667 mClosingApps.clear();
10668
10669 // This has changed the visibility of windows, so perform
10670 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010671 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010673 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10674 assignLayersLocked();
10675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010677 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010678 }
10679 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010680
Dianne Hackborn16064f92010-03-25 00:47:24 -070010681 int adjResult = 0;
10682
Dianne Hackborna8f60182009-09-01 19:01:50 -070010683 if (!animating && mAppTransitionRunning) {
10684 // We have finished the animation of an app transition. To do
10685 // this, we have delayed a lot of operations like showing and
10686 // hiding apps, moving apps in Z-order, etc. The app token list
10687 // reflects the correct Z-order, but the window list may now
10688 // be out of sync with it. So here we will just rebuild the
10689 // entire app window list. Fun!
10690 mAppTransitionRunning = false;
10691 // Clear information about apps that were moving.
10692 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010693
Dianne Hackborna8f60182009-09-01 19:01:50 -070010694 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010695 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010696 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010697 moveInputMethodWindowsIfNeededLocked(false);
10698 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010699 // Since the window list has been rebuilt, focus might
10700 // have to be recomputed since the actual order of windows
10701 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010702 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010703 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010704
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010705 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010706 // At this point, there was a window with a wallpaper that
10707 // was force hiding other windows behind it, but now it
10708 // is going away. This may be simple -- just animate
10709 // away the wallpaper and its window -- or it may be
10710 // hard -- the wallpaper now needs to be shown behind
10711 // something that was hidden.
10712 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010713 if (mLowerWallpaperTarget != null
10714 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010715 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010716 "wallpaperForceHiding changed with lower="
10717 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010718 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010719 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10720 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10721 if (mLowerWallpaperTarget.mAppToken.hidden) {
10722 // The lower target has become hidden before we
10723 // actually started the animation... let's completely
10724 // re-evaluate everything.
10725 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010726 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010727 }
10728 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010729 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010730 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010731 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010732 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010733 + " NEW: " + mWallpaperTarget
10734 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010735 if (mLowerWallpaperTarget == null) {
10736 // Whoops, we don't need a special wallpaper animation.
10737 // Clear them out.
10738 forceHiding = false;
10739 for (i=N-1; i>=0; i--) {
10740 WindowState w = (WindowState)mWindows.get(i);
10741 if (w.mSurface != null) {
10742 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010743 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010744 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010745 forceHiding = true;
10746 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10747 if (!w.mAnimating) {
10748 // We set the animation above so it
10749 // is not yet running.
10750 w.clearAnimation();
10751 }
10752 }
10753 }
10754 }
10755 }
10756 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010757
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010758 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010759 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010760 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010761 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010762 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010763
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010764 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010765 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010766 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010767 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010768 assignLayersLocked();
10769 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010770 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010771 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010772 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010773 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010774
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010775 if (mFocusMayChange) {
10776 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010777 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010778 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010779 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010780 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010781 }
10782
10783 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010784 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010785 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010786
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010787 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10788 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010789
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010790 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010791
10792 // THIRD LOOP: Update the surfaces of all windows.
10793
10794 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10795
10796 boolean obscured = false;
10797 boolean blurring = false;
10798 boolean dimming = false;
10799 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010800 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010801 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010802
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010803 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 for (i=N-1; i>=0; i--) {
10806 WindowState w = (WindowState)mWindows.get(i);
10807
10808 boolean displayed = false;
10809 final WindowManager.LayoutParams attrs = w.mAttrs;
10810 final int attrFlags = attrs.flags;
10811
10812 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010813 // XXX NOTE: The logic here could be improved. We have
10814 // the decision about whether to resize a window separated
10815 // from whether to hide the surface. This can cause us to
10816 // resize a surface even if we are going to hide it. You
10817 // can see this by (1) holding device in landscape mode on
10818 // home screen; (2) tapping browser icon (device will rotate
10819 // to landscape; (3) tap home. The wallpaper will be resized
10820 // in step 2 but then immediately hidden, causing us to
10821 // have to resize and then redraw it again in step 3. It
10822 // would be nice to figure out how to avoid this, but it is
10823 // difficult because we do need to resize surfaces in some
10824 // cases while they are hidden such as when first showing a
10825 // window.
10826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010827 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010828 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 TAG, "Placing surface #" + i + " " + w.mSurface
10830 + ": new=" + w.mShownFrame + ", old="
10831 + w.mLastShownFrame);
10832
10833 boolean resize;
10834 int width, height;
10835 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10836 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10837 w.mLastRequestedHeight != w.mRequestedHeight;
10838 // for a scaled surface, we just want to use
10839 // the requested size.
10840 width = w.mRequestedWidth;
10841 height = w.mRequestedHeight;
10842 w.mLastRequestedWidth = width;
10843 w.mLastRequestedHeight = height;
10844 w.mLastShownFrame.set(w.mShownFrame);
10845 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010846 if (SHOW_TRANSACTIONS) logSurface(w,
10847 "POS " + w.mShownFrame.left
10848 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010849 w.mSurfaceX = w.mShownFrame.left;
10850 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10852 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010853 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854 if (!recoveringMemory) {
10855 reclaimSomeSurfaceMemoryLocked(w, "position");
10856 }
10857 }
10858 } else {
10859 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10860 width = w.mShownFrame.width();
10861 height = w.mShownFrame.height();
10862 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 }
10864
10865 if (resize) {
10866 if (width < 1) width = 1;
10867 if (height < 1) height = 1;
10868 if (w.mSurface != null) {
10869 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010870 if (SHOW_TRANSACTIONS) logSurface(w,
10871 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010872 + w.mShownFrame.top + " SIZE "
10873 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010874 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010875 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010876 w.mSurfaceW = width;
10877 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010878 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010879 w.mSurfaceX = w.mShownFrame.left;
10880 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 w.mSurface.setPosition(w.mShownFrame.left,
10882 w.mShownFrame.top);
10883 } catch (RuntimeException e) {
10884 // If something goes wrong with the surface (such
10885 // as running out of memory), don't take down the
10886 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010887 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 + "size=(" + width + "x" + height
10889 + "), pos=(" + w.mShownFrame.left
10890 + "," + w.mShownFrame.top + ")", e);
10891 if (!recoveringMemory) {
10892 reclaimSomeSurfaceMemoryLocked(w, "size");
10893 }
10894 }
10895 }
10896 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010897 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 w.mContentInsetsChanged =
10899 !w.mLastContentInsets.equals(w.mContentInsets);
10900 w.mVisibleInsetsChanged =
10901 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010902 boolean configChanged =
10903 w.mConfiguration != mCurConfiguration
10904 && (w.mConfiguration == null
10905 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010906 if (DEBUG_CONFIGURATION && configChanged) {
10907 Slog.v(TAG, "Win " + w + " config changed: "
10908 + mCurConfiguration);
10909 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010910 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010911 + ": configChanged=" + configChanged
10912 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010913 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010914 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010915 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010916 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010917 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 w.mLastFrame.set(w.mFrame);
10919 w.mLastContentInsets.set(w.mContentInsets);
10920 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010921 // If the screen is currently frozen, then keep
10922 // it frozen until this window draws at its new
10923 // orientation.
10924 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010925 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010926 "Resizing while display frozen: " + w);
10927 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010928 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010929 mWindowsFreezingScreen = true;
10930 // XXX should probably keep timeout from
10931 // when we first froze the display.
10932 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10933 mH.sendMessageDelayed(mH.obtainMessage(
10934 H.WINDOW_FREEZE_TIMEOUT), 2000);
10935 }
10936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010937 // If the orientation is changing, then we need to
10938 // hold off on unfreezing the display until this
10939 // window has been redrawn; to do that, we need
10940 // to go through the process of getting informed
10941 // by the application when it has finished drawing.
10942 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010943 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010944 "Orientation start waiting for draw in "
10945 + w + ", surface " + w.mSurface);
10946 w.mDrawPending = true;
10947 w.mCommitDrawPending = false;
10948 w.mReadyToShow = false;
10949 if (w.mAppToken != null) {
10950 w.mAppToken.allDrawn = false;
10951 }
10952 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010953 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010954 "Resizing window " + w + " to " + w.mFrame);
10955 mResizingWindows.add(w);
10956 } else if (w.mOrientationChanging) {
10957 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010958 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010959 "Orientation not waiting for draw in "
10960 + w + ", surface " + w.mSurface);
10961 w.mOrientationChanging = false;
10962 }
10963 }
10964 }
10965
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010966 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 if (!w.mLastHidden) {
10968 //dump();
10969 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010970 if (SHOW_TRANSACTIONS) logSurface(w,
10971 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010973 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 try {
10975 w.mSurface.hide();
10976 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010977 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 }
10979 }
Jeff Brown349703e2010-06-22 01:27:15 -070010980 if (ENABLE_NATIVE_INPUT_DISPATCH) {
10981 mInputMonitor.windowIsBecomingInvisibleLw(w);
10982 } else {
10983 mKeyWaiter.releasePendingPointerLocked(w.mSession);
10984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010985 }
10986 // If we are waiting for this window to handle an
10987 // orientation change, well, it is hidden, so
10988 // doesn't really matter. Note that this does
10989 // introduce a potential glitch if the window
10990 // becomes unhidden before it has drawn for the
10991 // new orientation.
10992 if (w.mOrientationChanging) {
10993 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010994 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 "Orientation change skips hidden " + w);
10996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010997 } else if (w.mLastLayer != w.mAnimLayer
10998 || w.mLastAlpha != w.mShownAlpha
10999 || w.mLastDsDx != w.mDsDx
11000 || w.mLastDtDx != w.mDtDx
11001 || w.mLastDsDy != w.mDsDy
11002 || w.mLastDtDy != w.mDtDy
11003 || w.mLastHScale != w.mHScale
11004 || w.mLastVScale != w.mVScale
11005 || w.mLastHidden) {
11006 displayed = true;
11007 w.mLastAlpha = w.mShownAlpha;
11008 w.mLastLayer = w.mAnimLayer;
11009 w.mLastDsDx = w.mDsDx;
11010 w.mLastDtDx = w.mDtDx;
11011 w.mLastDsDy = w.mDsDy;
11012 w.mLastDtDy = w.mDtDy;
11013 w.mLastHScale = w.mHScale;
11014 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011015 if (SHOW_TRANSACTIONS) logSurface(w,
11016 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011017 + " matrix=[" + (w.mDsDx*w.mHScale)
11018 + "," + (w.mDtDx*w.mVScale)
11019 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011020 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011021 if (w.mSurface != null) {
11022 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011023 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011025 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 w.mSurface.setLayer(w.mAnimLayer);
11027 w.mSurface.setMatrix(
11028 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
11029 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
11030 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011031 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011032 if (!recoveringMemory) {
11033 reclaimSomeSurfaceMemoryLocked(w, "update");
11034 }
11035 }
11036 }
11037
11038 if (w.mLastHidden && !w.mDrawPending
11039 && !w.mCommitDrawPending
11040 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011041 if (SHOW_TRANSACTIONS) logSurface(w,
11042 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011043 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 + " during relayout");
11045 if (showSurfaceRobustlyLocked(w)) {
11046 w.mHasDrawn = true;
11047 w.mLastHidden = false;
11048 } else {
11049 w.mOrientationChanging = false;
11050 }
11051 }
11052 if (w.mSurface != null) {
11053 w.mToken.hasVisible = true;
11054 }
11055 } else {
11056 displayed = true;
11057 }
11058
11059 if (displayed) {
11060 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080011061 if (attrs.width == LayoutParams.MATCH_PARENT
11062 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011063 covered = true;
11064 }
11065 }
11066 if (w.mOrientationChanging) {
11067 if (w.mDrawPending || w.mCommitDrawPending) {
11068 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011069 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011070 "Orientation continue waiting for draw in " + w);
11071 } else {
11072 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011073 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011074 "Orientation change complete in " + w);
11075 }
11076 }
11077 w.mToken.hasVisible = true;
11078 }
11079 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011080 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011081 "Orientation change skips hidden " + w);
11082 w.mOrientationChanging = false;
11083 }
11084
11085 final boolean canBeSeen = w.isDisplayedLw();
11086
11087 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
11088 focusDisplayed = true;
11089 }
11090
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011091 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011094 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011095 if (w.mSurface != null) {
11096 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
11097 holdScreen = w.mSession;
11098 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070011099 if (!syswin && w.mAttrs.screenBrightness >= 0
11100 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101 screenBrightness = w.mAttrs.screenBrightness;
11102 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050011103 if (!syswin && w.mAttrs.buttonBrightness >= 0
11104 && buttonBrightness < 0) {
11105 buttonBrightness = w.mAttrs.buttonBrightness;
11106 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050011107 if (canBeSeen
11108 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
11109 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
11110 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070011111 syswin = true;
11112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011113 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011114
Dianne Hackborn25994b42009-09-04 14:21:19 -070011115 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
11116 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011117 // This window completely covers everything behind it,
11118 // so we want to leave all of them as unblurred (for
11119 // performance reasons).
11120 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011121 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011122 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011123 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011124 obscured = true;
11125 if (mBackgroundFillerSurface == null) {
11126 try {
11127 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011128 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011129 0, dw, dh,
11130 PixelFormat.OPAQUE,
11131 Surface.FX_SURFACE_NORMAL);
11132 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011133 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011134 }
11135 }
11136 try {
11137 mBackgroundFillerSurface.setPosition(0, 0);
11138 mBackgroundFillerSurface.setSize(dw, dh);
11139 // Using the same layer as Dim because they will never be shown at the
11140 // same time.
11141 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
11142 mBackgroundFillerSurface.show();
11143 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011144 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011145 }
11146 backgroundFillerShown = true;
11147 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011148 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011150 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151 + ": blurring=" + blurring
11152 + " obscured=" + obscured
11153 + " displayed=" + displayed);
11154 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
11155 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011156 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011158 if (mDimAnimator == null) {
11159 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011161 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011162 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011164 }
11165 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
11166 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011167 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011170 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011171 + mBlurSurface + ": CREATE");
11172 try {
Romain Guy06882f82009-06-10 13:36:04 -070011173 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011174 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 -1, 16, 16,
11176 PixelFormat.OPAQUE,
11177 Surface.FX_SURFACE_BLUR);
11178 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011179 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011180 }
11181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011183 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
11184 + mBlurSurface + ": pos=(0,0) (" +
11185 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011186 mBlurSurface.setPosition(0, 0);
11187 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070011188 mBlurSurface.setLayer(w.mAnimLayer-2);
11189 if (!mBlurShown) {
11190 try {
11191 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
11192 + mBlurSurface + ": SHOW");
11193 mBlurSurface.show();
11194 } catch (RuntimeException e) {
11195 Slog.w(TAG, "Failure showing blur surface", e);
11196 }
11197 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198 }
11199 }
11200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011201 }
11202 }
11203 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011204
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070011205 if (obscuredChanged && mWallpaperTarget == w) {
11206 // This is the wallpaper target and its obscured state
11207 // changed... make sure the current wallaper's visibility
11208 // has been updated accordingly.
11209 updateWallpaperVisibilityLocked();
11210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011211 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011212
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011213 if (backgroundFillerShown == false && mBackgroundFillerShown) {
11214 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011215 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011216 try {
11217 mBackgroundFillerSurface.hide();
11218 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011219 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070011220 }
11221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011222
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011223 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080011224 animating |= mDimAnimator.updateSurface(dimming, currentTime,
11225 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 }
Romain Guy06882f82009-06-10 13:36:04 -070011227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011228 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011229 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011230 + ": HIDE");
11231 try {
11232 mBlurSurface.hide();
11233 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011234 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011235 }
11236 mBlurShown = false;
11237 }
11238
Joe Onorato8a9b2202010-02-26 18:56:32 -080011239 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011241 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011242 }
11243
11244 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070011245
Joe Onorato8a9b2202010-02-26 18:56:32 -080011246 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011247 "With display frozen, orientationChangeComplete="
11248 + orientationChangeComplete);
11249 if (orientationChangeComplete) {
11250 if (mWindowsFreezingScreen) {
11251 mWindowsFreezingScreen = false;
11252 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
11253 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011254 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 }
Romain Guy06882f82009-06-10 13:36:04 -070011256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011257 i = mResizingWindows.size();
11258 if (i > 0) {
11259 do {
11260 i--;
11261 WindowState win = mResizingWindows.get(i);
11262 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011263 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
11264 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011265 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011266 boolean configChanged =
11267 win.mConfiguration != mCurConfiguration
11268 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011269 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
11270 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
11271 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011272 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011273 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011274 + " / " + mCurConfiguration + " / 0x"
11275 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011276 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070011277 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278 win.mClient.resized(win.mFrame.width(),
11279 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011280 win.mLastVisibleInsets, win.mDrawPending,
11281 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 win.mContentInsetsChanged = false;
11283 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080011284 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 } catch (RemoteException e) {
11286 win.mOrientationChanging = false;
11287 }
11288 } while (i > 0);
11289 mResizingWindows.clear();
11290 }
Romain Guy06882f82009-06-10 13:36:04 -070011291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011292 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011293 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011294 i = mDestroySurface.size();
11295 if (i > 0) {
11296 do {
11297 i--;
11298 WindowState win = mDestroySurface.get(i);
11299 win.mDestroying = false;
11300 if (mInputMethodWindow == win) {
11301 mInputMethodWindow = null;
11302 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011303 if (win == mWallpaperTarget) {
11304 wallpaperDestroyed = true;
11305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011306 win.destroySurfaceLocked();
11307 } while (i > 0);
11308 mDestroySurface.clear();
11309 }
11310
11311 // Time to remove any exiting tokens?
11312 for (i=mExitingTokens.size()-1; i>=0; i--) {
11313 WindowToken token = mExitingTokens.get(i);
11314 if (!token.hasVisible) {
11315 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011316 if (token.windowType == TYPE_WALLPAPER) {
11317 mWallpaperTokens.remove(token);
11318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011319 }
11320 }
11321
11322 // Time to remove any exiting applications?
11323 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
11324 AppWindowToken token = mExitingAppTokens.get(i);
11325 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070011326 // Make sure there is no animation running on this token,
11327 // so any windows associated with it will be removed as
11328 // soon as their animations are complete
11329 token.animation = null;
11330 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331 mAppTokens.remove(token);
11332 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011333 if (mLastEnterAnimToken == token) {
11334 mLastEnterAnimToken = null;
11335 mLastEnterAnimParams = null;
11336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011337 }
11338 }
11339
Dianne Hackborna8f60182009-09-01 19:01:50 -070011340 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011341
Dianne Hackborna8f60182009-09-01 19:01:50 -070011342 if (!animating && mAppTransitionRunning) {
11343 // We have finished the animation of an app transition. To do
11344 // this, we have delayed a lot of operations like showing and
11345 // hiding apps, moving apps in Z-order, etc. The app token list
11346 // reflects the correct Z-order, but the window list may now
11347 // be out of sync with it. So here we will just rebuild the
11348 // entire app window list. Fun!
11349 mAppTransitionRunning = false;
11350 needRelayout = true;
11351 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011352 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070011353 // Clear information about apps that were moving.
11354 mToBottomApps.clear();
11355 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 if (focusDisplayed) {
11358 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
11359 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011360 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011361 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011362 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011363 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011364 requestAnimationLocked(0);
11365 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
11367 }
Jeff Brown8e03b752010-06-13 19:16:55 -070011368 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 if (screenBrightness < 0 || screenBrightness > 1.0f) {
11370 mPowerManager.setScreenBrightnessOverride(-1);
11371 } else {
11372 mPowerManager.setScreenBrightnessOverride((int)
11373 (screenBrightness * Power.BRIGHTNESS_ON));
11374 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050011375 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
11376 mPowerManager.setButtonBrightnessOverride(-1);
11377 } else {
11378 mPowerManager.setButtonBrightnessOverride((int)
11379 (buttonBrightness * Power.BRIGHTNESS_ON));
11380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011381 if (holdScreen != mHoldingScreenOn) {
11382 mHoldingScreenOn = holdScreen;
11383 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
11384 mH.sendMessage(m);
11385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011386
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011387 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011388 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011389 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
11390 LocalPowerManager.BUTTON_EVENT, true);
11391 mTurnOnScreen = false;
11392 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011393
11394 // Check to see if we are now in a state where the screen should
11395 // be enabled, because the window obscured flags have changed.
11396 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011398
11399 /**
11400 * Must be called with the main window manager lock held.
11401 */
11402 void setHoldScreenLocked(boolean holding) {
11403 boolean state = mHoldingScreenWakeLock.isHeld();
11404 if (holding != state) {
11405 if (holding) {
11406 mHoldingScreenWakeLock.acquire();
11407 } else {
11408 mPolicy.screenOnStoppedLw();
11409 mHoldingScreenWakeLock.release();
11410 }
11411 }
11412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011413
11414 void requestAnimationLocked(long delay) {
11415 if (!mAnimationPending) {
11416 mAnimationPending = true;
11417 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
11418 }
11419 }
Romain Guy06882f82009-06-10 13:36:04 -070011420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 /**
11422 * Have the surface flinger show a surface, robustly dealing with
11423 * error conditions. In particular, if there is not enough memory
11424 * to show the surface, then we will try to get rid of other surfaces
11425 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070011426 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011427 * @return Returns true if the surface was successfully shown.
11428 */
11429 boolean showSurfaceRobustlyLocked(WindowState win) {
11430 try {
11431 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011432 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011433 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011434 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011435 if (DEBUG_VISIBILITY) Slog.v(TAG,
11436 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011437 win.mTurnOnScreen = false;
11438 mTurnOnScreen = true;
11439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011440 }
11441 return true;
11442 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011443 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 }
Romain Guy06882f82009-06-10 13:36:04 -070011445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011446 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070011447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011448 return false;
11449 }
Romain Guy06882f82009-06-10 13:36:04 -070011450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
11452 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070011453
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011454 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070011456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011457 if (mForceRemoves == null) {
11458 mForceRemoves = new ArrayList<WindowState>();
11459 }
Romain Guy06882f82009-06-10 13:36:04 -070011460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011461 long callingIdentity = Binder.clearCallingIdentity();
11462 try {
11463 // There was some problem... first, do a sanity check of the
11464 // window list to make sure we haven't left any dangling surfaces
11465 // around.
11466 int N = mWindows.size();
11467 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011468 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 for (int i=0; i<N; i++) {
11470 WindowState ws = (WindowState)mWindows.get(i);
11471 if (ws.mSurface != null) {
11472 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011473 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011474 + ws + " surface=" + ws.mSurface
11475 + " token=" + win.mToken
11476 + " pid=" + ws.mSession.mPid
11477 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011478 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011479 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011480 ws.mSurface = null;
11481 mForceRemoves.add(ws);
11482 i--;
11483 N--;
11484 leakedSurface = true;
11485 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011486 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011487 + ws + " surface=" + ws.mSurface
11488 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011489 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011490 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011491 ws.mSurface = null;
11492 leakedSurface = true;
11493 }
11494 }
11495 }
Romain Guy06882f82009-06-10 13:36:04 -070011496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011497 boolean killedApps = false;
11498 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011499 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500 SparseIntArray pidCandidates = new SparseIntArray();
11501 for (int i=0; i<N; i++) {
11502 WindowState ws = (WindowState)mWindows.get(i);
11503 if (ws.mSurface != null) {
11504 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
11505 }
11506 }
11507 if (pidCandidates.size() > 0) {
11508 int[] pids = new int[pidCandidates.size()];
11509 for (int i=0; i<pids.length; i++) {
11510 pids[i] = pidCandidates.keyAt(i);
11511 }
11512 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070011513 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011514 killedApps = true;
11515 }
11516 } catch (RemoteException e) {
11517 }
11518 }
11519 }
Romain Guy06882f82009-06-10 13:36:04 -070011520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011521 if (leakedSurface || killedApps) {
11522 // We managed to reclaim some memory, so get rid of the trouble
11523 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011524 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011525 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011526 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011527 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 win.mSurface = null;
11529 }
Romain Guy06882f82009-06-10 13:36:04 -070011530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 try {
11532 win.mClient.dispatchGetNewSurface();
11533 } catch (RemoteException e) {
11534 }
11535 }
11536 } finally {
11537 Binder.restoreCallingIdentity(callingIdentity);
11538 }
11539 }
Romain Guy06882f82009-06-10 13:36:04 -070011540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011541 private boolean updateFocusedWindowLocked(int mode) {
11542 WindowState newFocus = computeFocusedWindowLocked();
11543 if (mCurrentFocus != newFocus) {
11544 // This check makes sure that we don't already have the focus
11545 // change message pending.
11546 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
11547 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011548 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011549 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
11550 final WindowState oldFocus = mCurrentFocus;
11551 mCurrentFocus = newFocus;
11552 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070011553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 final WindowState imWindow = mInputMethodWindow;
11555 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011556 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011557 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011558 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
11559 mLayoutNeeded = true;
11560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011561 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
11562 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011563 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
11564 // Client will do the layout, but we need to assign layers
11565 // for handleNewWindowLocked() below.
11566 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011567 }
11568 }
Jeff Brown349703e2010-06-22 01:27:15 -070011569
11570 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
11571 // If we defer assigning layers, then the caller is responsible for
11572 // doing this part.
11573 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011575 return true;
11576 }
11577 return false;
11578 }
Jeff Brown349703e2010-06-22 01:27:15 -070011579
11580 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
11581 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11582 mInputMonitor.setInputFocusLw(mCurrentFocus);
11583 } else {
11584 if (mCurrentFocus != null) {
11585 mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
11586 }
11587 }
11588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011589
11590 private WindowState computeFocusedWindowLocked() {
11591 WindowState result = null;
11592 WindowState win;
11593
11594 int i = mWindows.size() - 1;
11595 int nextAppIndex = mAppTokens.size()-1;
11596 WindowToken nextApp = nextAppIndex >= 0
11597 ? mAppTokens.get(nextAppIndex) : null;
11598
11599 while (i >= 0) {
11600 win = (WindowState)mWindows.get(i);
11601
Joe Onorato8a9b2202010-02-26 18:56:32 -080011602 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011603 TAG, "Looking for focus: " + i
11604 + " = " + win
11605 + ", flags=" + win.mAttrs.flags
11606 + ", canReceive=" + win.canReceiveKeys());
11607
11608 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011610 // If this window's application has been removed, just skip it.
11611 if (thisApp != null && thisApp.removed) {
11612 i--;
11613 continue;
11614 }
Romain Guy06882f82009-06-10 13:36:04 -070011615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011616 // If there is a focused app, don't allow focus to go to any
11617 // windows below it. If this is an application window, step
11618 // through the app tokens until we find its app.
11619 if (thisApp != null && nextApp != null && thisApp != nextApp
11620 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11621 int origAppIndex = nextAppIndex;
11622 while (nextAppIndex > 0) {
11623 if (nextApp == mFocusedApp) {
11624 // Whoops, we are below the focused app... no focus
11625 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011626 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011627 TAG, "Reached focused app: " + mFocusedApp);
11628 return null;
11629 }
11630 nextAppIndex--;
11631 nextApp = mAppTokens.get(nextAppIndex);
11632 if (nextApp == thisApp) {
11633 break;
11634 }
11635 }
11636 if (thisApp != nextApp) {
11637 // Uh oh, the app token doesn't exist! This shouldn't
11638 // happen, but if it does we can get totally hosed...
11639 // so restart at the original app.
11640 nextAppIndex = origAppIndex;
11641 nextApp = mAppTokens.get(nextAppIndex);
11642 }
11643 }
11644
11645 // Dispatch to this window if it is wants key events.
11646 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011647 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011648 TAG, "Found focus @ " + i + " = " + win);
11649 result = win;
11650 break;
11651 }
11652
11653 i--;
11654 }
11655
11656 return result;
11657 }
11658
11659 private void startFreezingDisplayLocked() {
11660 if (mDisplayFrozen) {
Chris Tate2ad63a92009-03-25 17:36:48 -070011661 // Freezing the display also suspends key event delivery, to
11662 // keep events from going astray while the display is reconfigured.
11663 // If someone has changed orientation again while the screen is
11664 // still frozen, the events will continue to be blocked while the
11665 // successive orientation change is processed. To prevent spurious
11666 // ANRs, we reset the event dispatch timeout in this case.
Jeff Brown349703e2010-06-22 01:27:15 -070011667 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
11668 synchronized (mKeyWaiter) {
11669 mKeyWaiter.mWasFrozen = true;
11670 }
Chris Tate2ad63a92009-03-25 17:36:48 -070011671 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011672 return;
11673 }
Romain Guy06882f82009-06-10 13:36:04 -070011674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011678 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 if (mFreezeGcPending != 0) {
11680 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011681 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 mH.removeMessages(H.FORCE_GC);
11683 Runtime.getRuntime().gc();
11684 mFreezeGcPending = now;
11685 }
11686 } else {
11687 mFreezeGcPending = now;
11688 }
Romain Guy06882f82009-06-10 13:36:04 -070011689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070011691
11692 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11693 mInputMonitor.freezeInputDispatchingLw();
11694 }
11695
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011696 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11697 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011698 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 mAppTransitionReady = true;
11700 }
Romain Guy06882f82009-06-10 13:36:04 -070011701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011702 if (PROFILE_ORIENTATION) {
11703 File file = new File("/data/system/frozen");
11704 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11705 }
11706 Surface.freezeDisplay(0);
11707 }
Romain Guy06882f82009-06-10 13:36:04 -070011708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011709 private void stopFreezingDisplayLocked() {
11710 if (!mDisplayFrozen) {
11711 return;
11712 }
Romain Guy06882f82009-06-10 13:36:04 -070011713
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011714 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11715 return;
11716 }
11717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011718 mDisplayFrozen = false;
11719 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11720 if (PROFILE_ORIENTATION) {
11721 Debug.stopMethodTracing();
11722 }
11723 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070011724
Chris Tate2ad63a92009-03-25 17:36:48 -070011725 // Reset the key delivery timeout on unfreeze, too. We force a wakeup here
11726 // too because regular key delivery processing should resume immediately.
Jeff Brown349703e2010-06-22 01:27:15 -070011727 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11728 mInputMonitor.thawInputDispatchingLw();
11729 } else {
11730 synchronized (mKeyWaiter) {
11731 mKeyWaiter.mWasFrozen = true;
11732 mKeyWaiter.notifyAll();
11733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011734 }
11735
Christopher Tateb696aee2010-04-02 19:08:30 -070011736 // While the display is frozen we don't re-compute the orientation
11737 // to avoid inconsistent states. However, something interesting
11738 // could have actually changed during that time so re-evaluate it
11739 // now to catch that.
11740 if (updateOrientationFromAppTokensLocked()) {
11741 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11742 }
11743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011744 // A little kludge: a lot could have happened while the
11745 // display was frozen, so now that we are coming back we
11746 // do a gc so that any remote references the system
11747 // processes holds on others can be released if they are
11748 // no longer needed.
11749 mH.removeMessages(H.FORCE_GC);
11750 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11751 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011753 mScreenFrozenLock.release();
11754 }
Romain Guy06882f82009-06-10 13:36:04 -070011755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011756 @Override
11757 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11758 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11759 != PackageManager.PERMISSION_GRANTED) {
11760 pw.println("Permission Denial: can't dump WindowManager from from pid="
11761 + Binder.getCallingPid()
11762 + ", uid=" + Binder.getCallingUid());
11763 return;
11764 }
Romain Guy06882f82009-06-10 13:36:04 -070011765
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011766 if (ENABLE_NATIVE_INPUT_DISPATCH) {
11767 pw.println("Input Dispatcher State:");
11768 mInputManager.dump(pw);
11769 } else {
11770 pw.println("Input State:");
11771 mQueue.dump(pw, " ");
11772 }
Dianne Hackborna2e92262010-03-02 17:19:29 -080011773 pw.println(" ");
11774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 synchronized(mWindowMap) {
11776 pw.println("Current Window Manager state:");
11777 for (int i=mWindows.size()-1; i>=0; i--) {
11778 WindowState w = (WindowState)mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011779 pw.print(" Window #"); pw.print(i); pw.print(' ');
11780 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 w.dump(pw, " ");
11782 }
11783 if (mInputMethodDialogs.size() > 0) {
11784 pw.println(" ");
11785 pw.println(" Input method dialogs:");
11786 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11787 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011788 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011789 }
11790 }
11791 if (mPendingRemove.size() > 0) {
11792 pw.println(" ");
11793 pw.println(" Remove pending for:");
11794 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11795 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011796 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11797 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011798 w.dump(pw, " ");
11799 }
11800 }
11801 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11802 pw.println(" ");
11803 pw.println(" Windows force removing:");
11804 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11805 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011806 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11807 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011808 w.dump(pw, " ");
11809 }
11810 }
11811 if (mDestroySurface.size() > 0) {
11812 pw.println(" ");
11813 pw.println(" Windows waiting to destroy their surface:");
11814 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11815 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011816 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11817 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011818 w.dump(pw, " ");
11819 }
11820 }
11821 if (mLosingFocus.size() > 0) {
11822 pw.println(" ");
11823 pw.println(" Windows losing focus:");
11824 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11825 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011826 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11827 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828 w.dump(pw, " ");
11829 }
11830 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011831 if (mResizingWindows.size() > 0) {
11832 pw.println(" ");
11833 pw.println(" Windows waiting to resize:");
11834 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11835 WindowState w = mResizingWindows.get(i);
11836 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11837 pw.print(w); pw.println(":");
11838 w.dump(pw, " ");
11839 }
11840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841 if (mSessions.size() > 0) {
11842 pw.println(" ");
11843 pw.println(" All active sessions:");
11844 Iterator<Session> it = mSessions.iterator();
11845 while (it.hasNext()) {
11846 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011847 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011848 s.dump(pw, " ");
11849 }
11850 }
11851 if (mTokenMap.size() > 0) {
11852 pw.println(" ");
11853 pw.println(" All tokens:");
11854 Iterator<WindowToken> it = mTokenMap.values().iterator();
11855 while (it.hasNext()) {
11856 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011857 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 token.dump(pw, " ");
11859 }
11860 }
11861 if (mTokenList.size() > 0) {
11862 pw.println(" ");
11863 pw.println(" Window token list:");
11864 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011865 pw.print(" #"); pw.print(i); pw.print(": ");
11866 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 }
11868 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011869 if (mWallpaperTokens.size() > 0) {
11870 pw.println(" ");
11871 pw.println(" Wallpaper tokens:");
11872 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11873 WindowToken token = mWallpaperTokens.get(i);
11874 pw.print(" Wallpaper #"); pw.print(i);
11875 pw.print(' '); pw.print(token); pw.println(':');
11876 token.dump(pw, " ");
11877 }
11878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011879 if (mAppTokens.size() > 0) {
11880 pw.println(" ");
11881 pw.println(" Application tokens in Z order:");
11882 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011883 pw.print(" App #"); pw.print(i); pw.print(": ");
11884 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011885 }
11886 }
11887 if (mFinishedStarting.size() > 0) {
11888 pw.println(" ");
11889 pw.println(" Finishing start of application tokens:");
11890 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11891 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011892 pw.print(" Finished Starting #"); pw.print(i);
11893 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011894 token.dump(pw, " ");
11895 }
11896 }
11897 if (mExitingTokens.size() > 0) {
11898 pw.println(" ");
11899 pw.println(" Exiting tokens:");
11900 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11901 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011902 pw.print(" Exiting #"); pw.print(i);
11903 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 token.dump(pw, " ");
11905 }
11906 }
11907 if (mExitingAppTokens.size() > 0) {
11908 pw.println(" ");
11909 pw.println(" Exiting application tokens:");
11910 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11911 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011912 pw.print(" Exiting App #"); pw.print(i);
11913 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 token.dump(pw, " ");
11915 }
11916 }
11917 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011918 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11919 pw.print(" mLastFocus="); pw.println(mLastFocus);
11920 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11921 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11922 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011923 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011924 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11925 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11926 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11927 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011928 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11929 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11930 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011931 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11932 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11933 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11934 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011935 if (mDimAnimator != null) {
11936 mDimAnimator.printTo(pw);
11937 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011938 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011939 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011940 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011941 pw.print(mInputMethodAnimLayerAdjustment);
11942 pw.print(" mWallpaperAnimLayerAdjustment=");
11943 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011944 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11945 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011946 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11947 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011948 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11949 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011950 pw.print(" mRotation="); pw.print(mRotation);
11951 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11952 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11953 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11954 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11955 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11956 pw.print(" mNextAppTransition=0x");
11957 pw.print(Integer.toHexString(mNextAppTransition));
11958 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011959 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011960 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011961 if (mNextAppTransitionPackage != null) {
11962 pw.print(" mNextAppTransitionPackage=");
11963 pw.print(mNextAppTransitionPackage);
11964 pw.print(", mNextAppTransitionEnter=0x");
11965 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11966 pw.print(", mNextAppTransitionExit=0x");
11967 pw.print(Integer.toHexString(mNextAppTransitionExit));
11968 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011969 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11970 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011971 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11972 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11973 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11974 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011975 if (mOpeningApps.size() > 0) {
11976 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11977 }
11978 if (mClosingApps.size() > 0) {
11979 pw.print(" mClosingApps="); pw.println(mClosingApps);
11980 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011981 if (mToTopApps.size() > 0) {
11982 pw.print(" mToTopApps="); pw.println(mToTopApps);
11983 }
11984 if (mToBottomApps.size() > 0) {
11985 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11986 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011987 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11988 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
Jeff Brown349703e2010-06-22 01:27:15 -070011989
11990 if (! ENABLE_NATIVE_INPUT_DISPATCH) {
11991 pw.println(" KeyWaiter state:");
11992 pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin);
11993 pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
11994 pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished);
11995 pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
11996 pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
11997 pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
11998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011999 }
12000 }
12001
Jeff Brown349703e2010-06-22 01:27:15 -070012002 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012003 public void monitor() {
12004 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050012005 synchronized (mKeyguardTokenWatcher) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012006 synchronized (mKeyWaiter) { }
Jeff Brown349703e2010-06-22 01:27:15 -070012007 synchronized (mInputMonitor) { }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012009
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070012010 public void virtualKeyFeedback(KeyEvent event) {
12011 mPolicy.keyFeedbackFromInput(event);
12012 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012013
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012014 /**
12015 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012016 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012017 */
12018 private static class DimAnimator {
12019 Surface mDimSurface;
12020 boolean mDimShown = false;
12021 float mDimCurrentAlpha;
12022 float mDimTargetAlpha;
12023 float mDimDeltaPerMs;
12024 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012025
12026 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012027
12028 DimAnimator (SurfaceSession session) {
12029 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012030 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012031 + mDimSurface + ": CREATE");
12032 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080012033 mDimSurface = new Surface(session, 0,
12034 "DimSurface",
12035 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012036 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010012037 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012038 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012039 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012040 }
12041 }
12042 }
12043
12044 /**
12045 * Show the dim surface.
12046 */
12047 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070012048 if (!mDimShown) {
12049 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
12050 dw + "x" + dh + ")");
12051 mDimShown = true;
12052 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012053 mLastDimWidth = dw;
12054 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070012055 mDimSurface.setPosition(0, 0);
12056 mDimSurface.setSize(dw, dh);
12057 mDimSurface.show();
12058 } catch (RuntimeException e) {
12059 Slog.w(TAG, "Failure showing dim surface", e);
12060 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070012061 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
12062 mLastDimWidth = dw;
12063 mLastDimHeight = dh;
12064 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012065 }
12066 }
12067
12068 /**
12069 * Set's the dim surface's layer and update dim parameters that will be used in
12070 * {@link updateSurface} after all windows are examined.
12071 */
12072 void updateParameters(WindowState w, long currentTime) {
12073 mDimSurface.setLayer(w.mAnimLayer-1);
12074
12075 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012076 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070012077 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012078 if (mDimTargetAlpha != target) {
12079 // If the desired dim level has changed, then
12080 // start an animation to it.
12081 mLastDimAnimTime = currentTime;
12082 long duration = (w.mAnimating && w.mAnimation != null)
12083 ? w.mAnimation.computeDurationHint()
12084 : DEFAULT_DIM_DURATION;
12085 if (target > mDimTargetAlpha) {
12086 // This is happening behind the activity UI,
12087 // so we can make it run a little longer to
12088 // give a stronger impression without disrupting
12089 // the user.
12090 duration *= DIM_DURATION_MULTIPLIER;
12091 }
12092 if (duration < 1) {
12093 // Don't divide by zero
12094 duration = 1;
12095 }
12096 mDimTargetAlpha = target;
12097 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
12098 }
12099 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012100
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012101 /**
12102 * Updating the surface's alpha. Returns true if the animation continues, or returns
12103 * false when the animation is finished and the dim surface is hidden.
12104 */
12105 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
12106 if (!dimming) {
12107 if (mDimTargetAlpha != 0) {
12108 mLastDimAnimTime = currentTime;
12109 mDimTargetAlpha = 0;
12110 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
12111 }
12112 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012113
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012114 boolean animating = false;
12115 if (mLastDimAnimTime != 0) {
12116 mDimCurrentAlpha += mDimDeltaPerMs
12117 * (currentTime-mLastDimAnimTime);
12118 boolean more = true;
12119 if (displayFrozen) {
12120 // If the display is frozen, there is no reason to animate.
12121 more = false;
12122 } else if (mDimDeltaPerMs > 0) {
12123 if (mDimCurrentAlpha > mDimTargetAlpha) {
12124 more = false;
12125 }
12126 } else if (mDimDeltaPerMs < 0) {
12127 if (mDimCurrentAlpha < mDimTargetAlpha) {
12128 more = false;
12129 }
12130 } else {
12131 more = false;
12132 }
12133
12134 // Do we need to continue animating?
12135 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012136 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012137 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
12138 mLastDimAnimTime = currentTime;
12139 mDimSurface.setAlpha(mDimCurrentAlpha);
12140 animating = true;
12141 } else {
12142 mDimCurrentAlpha = mDimTargetAlpha;
12143 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012144 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012145 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
12146 mDimSurface.setAlpha(mDimCurrentAlpha);
12147 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012148 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012149 + ": HIDE");
12150 try {
12151 mDimSurface.hide();
12152 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012153 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012154 }
12155 mDimShown = false;
12156 }
12157 }
12158 }
12159 return animating;
12160 }
12161
12162 public void printTo(PrintWriter pw) {
12163 pw.print(" mDimShown="); pw.print(mDimShown);
12164 pw.print(" current="); pw.print(mDimCurrentAlpha);
12165 pw.print(" target="); pw.print(mDimTargetAlpha);
12166 pw.print(" delta="); pw.print(mDimDeltaPerMs);
12167 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
12168 }
12169 }
12170
12171 /**
12172 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
12173 * This is used for opening/closing transition for apps in compatible mode.
12174 */
12175 private static class FadeInOutAnimation extends Animation {
12176 int mWidth;
12177 boolean mFadeIn;
12178
12179 public FadeInOutAnimation(boolean fadeIn) {
12180 setInterpolator(new AccelerateInterpolator());
12181 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
12182 mFadeIn = fadeIn;
12183 }
12184
12185 @Override
12186 protected void applyTransformation(float interpolatedTime, Transformation t) {
12187 float x = interpolatedTime;
12188 if (!mFadeIn) {
12189 x = 1.0f - x; // reverse the interpolation for fade out
12190 }
12191 if (x < 0.5) {
12192 // move the window out of the screen.
12193 t.getMatrix().setTranslate(mWidth, 0);
12194 } else {
12195 t.getMatrix().setTranslate(0, 0);// show
12196 t.setAlpha((x - 0.5f) * 2);
12197 }
12198 }
12199
12200 @Override
12201 public void initialize(int width, int height, int parentWidth, int parentHeight) {
12202 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
12203 mWidth = width;
12204 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012205
12206 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070012207 public int getZAdjustment() {
12208 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012209 }
12210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211}