blob: 817f0b2fa5093e8a9355c76aef3dece64e65ab98 [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
21import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -070025import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Joe Onorato93056472010-09-10 10:30:46 -040026import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR;
28import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
29import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070030import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
32import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import static android.view.WindowManager.LayoutParams.MEMORY_TYPE_PUSH_BUFFERS;
34import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
35import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
36import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
37import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070038import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
40import com.android.internal.app.IBatteryStats;
41import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080042import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070043import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import com.android.internal.view.IInputContext;
45import com.android.internal.view.IInputMethodClient;
46import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080047import com.android.internal.view.WindowManagerPolicyThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import com.android.server.am.BatteryStatsService;
49
50import android.Manifest;
51import android.app.ActivityManagerNative;
52import android.app.IActivityManager;
Jim Millerd6b57052010-06-07 17:52:42 -070053import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070054import android.content.BroadcastReceiver;
Christopher Tatea53146c2010-09-07 11:57:52 -070055import android.content.ClipData;
56import android.content.ClipDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070058import android.content.Intent;
59import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.content.pm.ActivityInfo;
61import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070062import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.content.res.Configuration;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070064import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.graphics.Matrix;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070066import android.graphics.Paint;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.graphics.PixelFormat;
68import android.graphics.Rect;
69import android.graphics.Region;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070070import android.graphics.Typeface;
71import android.graphics.Paint.FontMetricsInt;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.BatteryStats;
73import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070074import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.os.Debug;
76import android.os.Handler;
77import android.os.IBinder;
78import android.os.LocalPowerManager;
79import android.os.Looper;
80import android.os.Message;
81import android.os.Parcel;
82import android.os.ParcelFileDescriptor;
83import android.os.Power;
84import android.os.PowerManager;
85import android.os.Process;
86import android.os.RemoteException;
87import android.os.ServiceManager;
88import android.os.SystemClock;
89import android.os.SystemProperties;
90import android.os.TokenWatcher;
91import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070092import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070094import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080095import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070097import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.view.Display;
Christopher Tatea53146c2010-09-07 11:57:52 -070099import android.view.DragEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.view.Gravity;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700101import android.view.HapticFeedbackConstants;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.view.IApplicationToken;
103import android.view.IOnKeyguardExitResult;
104import android.view.IRotationWatcher;
105import android.view.IWindow;
106import android.view.IWindowManager;
107import android.view.IWindowSession;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700108import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700109import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700110import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700111import android.view.InputHandler;
112import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.KeyEvent;
114import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Surface;
116import android.view.SurfaceSession;
117import android.view.View;
118import android.view.ViewTreeObserver;
119import android.view.WindowManager;
120import android.view.WindowManagerImpl;
121import android.view.WindowManagerPolicy;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700122import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700124import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import android.view.animation.Animation;
126import android.view.animation.AnimationUtils;
127import android.view.animation.Transformation;
128
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700129import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700131import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.File;
133import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700134import java.io.FileInputStream;
135import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.io.IOException;
137import java.io.OutputStream;
138import java.io.OutputStreamWriter;
139import java.io.PrintWriter;
140import java.io.StringWriter;
141import java.net.Socket;
142import java.util.ArrayList;
143import java.util.HashMap;
144import java.util.HashSet;
145import java.util.Iterator;
146import java.util.List;
147
148/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700149public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700150 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 static final String TAG = "WindowManager";
152 static final boolean DEBUG = false;
153 static final boolean DEBUG_FOCUS = false;
154 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800155 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800156 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static final boolean DEBUG_LAYERS = false;
158 static final boolean DEBUG_INPUT = false;
159 static final boolean DEBUG_INPUT_METHOD = false;
160 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700161 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700163 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_APP_TRANSITIONS = false;
165 static final boolean DEBUG_STARTING_WINDOW = false;
166 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700167 static final boolean DEBUG_WALLPAPER = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700168 static final boolean DEBUG_DRAG = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700170 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean PROFILE_ORIENTATION = false;
173 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700174 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 /** How much to multiply the policy's type layer, to reserve room
177 * for multiple windows of the same type and Z-ordering adjustment
178 * with TYPE_LAYER_OFFSET. */
179 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
182 * or below others in the same layer. */
183 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 /** How much to increment the layer for each window, to reserve room
186 * for effect surfaces between them.
187 */
188 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 /** The maximum length we will accept for a loaded animation duration:
191 * this is 10 seconds.
192 */
193 static final int MAX_ANIMATION_DURATION = 10*1000;
194
195 /** Amount of time (in milliseconds) to animate the dim surface from one
196 * value to another, when no window animation is driving it.
197 */
198 static final int DEFAULT_DIM_DURATION = 200;
199
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700200 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
201 * compatible windows.
202 */
203 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 /** Adjustment to time to perform a dim, to make it more dramatic.
206 */
207 static final int DIM_DURATION_MULTIPLIER = 6;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700208
209 // Maximum number of milliseconds to wait for input event injection.
210 // FIXME is this value reasonable?
211 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700212
213 // Default input dispatching timeout in nanoseconds.
214 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700215
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700222 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223
224 /**
225 * Condition waited on by {@link #reenableKeyguard} to know the call to
226 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500227 * This is set to true only if mKeyguardTokenWatcher.acquired() has
228 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500230 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
Jim Miller284b62e2010-06-08 14:27:42 -0700232 private static final int ALLOW_DISABLE_YES = 1;
233 private static final int ALLOW_DISABLE_NO = 0;
234 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
235 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
236
Mike Lockwood983ee092009-11-22 01:42:24 -0500237 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
238 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700240 if (shouldAllowDisableKeyguard()) {
241 mPolicy.enableKeyguard(false);
242 mKeyguardDisabled = true;
243 } else {
244 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 }
247 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700248 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500249 synchronized (mKeyguardTokenWatcher) {
250 mKeyguardDisabled = false;
251 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
253 }
254 };
255
Jim Miller284b62e2010-06-08 14:27:42 -0700256 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
257 @Override
258 public void onReceive(Context context, Intent intent) {
259 mPolicy.enableKeyguard(true);
260 synchronized(mKeyguardTokenWatcher) {
261 // lazily evaluate this next time we're asked to disable keyguard
262 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
263 mKeyguardDisabled = false;
264 }
265 }
266 };
267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 final Context mContext;
269
270 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
275
276 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 /**
281 * All currently active sessions with clients.
282 */
283 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 /**
286 * Mapping from an IWindow IBinder to the server's Window object.
287 * This is also used as the lock for all of our state.
288 */
289 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
290
291 /**
292 * Mapping from a token IBinder to a WindowToken object.
293 */
294 final HashMap<IBinder, WindowToken> mTokenMap =
295 new HashMap<IBinder, WindowToken>();
296
297 /**
298 * The same tokens as mTokenMap, stored in a list for efficient iteration
299 * over them.
300 */
301 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 /**
304 * Window tokens that are in the process of exiting, but still
305 * on screen for animations.
306 */
307 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
308
309 /**
310 * Z-ordered (bottom-most first) list of all application tokens, for
311 * controlling the ordering of windows in different applications. This
312 * contains WindowToken objects.
313 */
314 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
315
316 /**
317 * Application tokens that are in the process of exiting, but still
318 * on screen for animations.
319 */
320 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
321
322 /**
323 * List of window tokens that have finished starting their application,
324 * and now need to have the policy remove their windows.
325 */
326 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
327
328 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700329 * This was the app token that was used to retrieve the last enter
330 * animation. It will be used for the next exit animation.
331 */
332 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800333
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700334 /**
335 * These were the layout params used to retrieve the last enter animation.
336 * They will be used for the next exit animation.
337 */
338 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800339
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700340 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 * Z-ordered (bottom-most first) list of all Window objects.
342 */
Jeff Browne33348b2010-07-15 23:54:05 -0700343 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344
345 /**
346 * Windows that are being resized. Used so we can tell the client about
347 * the resize after closing the transaction in which we resized the
348 * underlying surface.
349 */
350 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
351
352 /**
353 * Windows whose animations have ended and now must be removed.
354 */
355 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
356
357 /**
358 * Windows whose surface should be destroyed.
359 */
360 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
361
362 /**
363 * Windows that have lost input focus and are waiting for the new
364 * focus window to be displayed before they are told about this.
365 */
366 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
367
368 /**
369 * This is set when we have run out of memory, and will either be an empty
370 * list or contain windows that need to be force removed.
371 */
372 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700377 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 Surface mBlurSurface;
379 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700380 Watermark mWatermark;
Romain Guy06882f82009-06-10 13:36:04 -0700381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 final float[] mTmpFloats = new float[9];
385
386 boolean mSafeMode;
387 boolean mDisplayEnabled = false;
388 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700389 int mInitialDisplayWidth = 0;
390 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 int mRotation = 0;
392 int mRequestedRotation = 0;
393 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700394 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 ArrayList<IRotationWatcher> mRotationWatchers
396 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 boolean mLayoutNeeded = true;
399 boolean mAnimationPending = false;
400 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800401 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 boolean mWindowsFreezingScreen = false;
403 long mFreezeGcPending = 0;
404 int mAppsFreezingScreen = 0;
405
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800406 int mLayoutSeq = 0;
407
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800408 // State while inside of layoutAndPlaceSurfacesLocked().
409 boolean mFocusMayChange;
410
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800411 Configuration mCurConfiguration = new Configuration();
412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 // This is held as long as we have the screen frozen, to give us time to
414 // perform a rotation animation when turning off shows the lock screen which
415 // changes the orientation.
416 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 // State management of app transitions. When we are preparing for a
419 // transition, mNextAppTransition will be the kind of transition to
420 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
421 // mOpeningApps and mClosingApps are the lists of tokens that will be
422 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700423 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700424 String mNextAppTransitionPackage;
425 int mNextAppTransitionEnter;
426 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700428 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 boolean mAppTransitionTimeout = false;
430 boolean mStartingIconInTransition = false;
431 boolean mSkipAppTransitionAnimation = false;
432 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
433 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700434 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
435 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 H mH = new H();
440
441 WindowState mCurrentFocus = null;
442 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 // This just indicates the window the input method is on top of, not
445 // necessarily the window its input is going to.
446 WindowState mInputMethodTarget = null;
447 WindowState mUpcomingInputMethodTarget = null;
448 boolean mInputMethodTargetWaitingAnim;
449 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 WindowState mInputMethodWindow = null;
452 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
453
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700454 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800455
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700456 // If non-null, this is the currently visible window that is associated
457 // with the wallpaper.
458 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700459 // If non-null, we are in the middle of animating from one wallpaper target
460 // to another, and this is the lower one in Z-order.
461 WindowState mLowerWallpaperTarget = null;
462 // If non-null, we are in the middle of animating from one wallpaper target
463 // to another, and this is the higher one in Z-order.
464 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700465 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700466 float mLastWallpaperX = -1;
467 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800468 float mLastWallpaperXStep = -1;
469 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700470 // This is set when we are waiting for a wallpaper to tell us it is done
471 // changing its scroll position.
472 WindowState mWaitingOnWallpaper;
473 // The last time we had a timeout when waiting for a wallpaper.
474 long mLastWallpaperTimeoutTime;
475 // We give a wallpaper up to 150ms to finish scrolling.
476 static final long WALLPAPER_TIMEOUT = 150;
477 // Time we wait after a timeout before trying to wait again.
478 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 AppWindowToken mFocusedApp = null;
481
482 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 float mWindowAnimationScale = 1.0f;
485 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700486
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700487 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488
489 // Who is holding the screen on.
490 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700491 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700492
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700493 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700496 * Drag/drop state
497 */
498 class DragState {
499 IBinder mToken;
500 Surface mSurface;
501 boolean mLocalOnly;
Chris Tate7b362e42010-11-04 16:02:52 -0700502 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700503 ClipData mData;
504 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700505 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700506 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700507 float mThumbOffsetX, mThumbOffsetY;
508 InputChannel mServerChannel, mClientChannel;
509 WindowState mTargetWindow;
510 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700511 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700512
513 private final Rect tmpRect = new Rect();
514
Chris Tate7b362e42010-11-04 16:02:52 -0700515 DragState(IBinder token, Surface surface, boolean localOnly, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700516 mToken = token;
517 mSurface = surface;
518 mLocalOnly = localOnly;
Chris Tate7b362e42010-11-04 16:02:52 -0700519 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700520 mNotifiedWindows = new ArrayList<WindowState>();
521 }
522
523 void reset() {
524 if (mSurface != null) {
525 mSurface.destroy();
526 }
527 mSurface = null;
528 mLocalOnly = false;
Chris Tate7b362e42010-11-04 16:02:52 -0700529 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700530 mToken = null;
531 mData = null;
532 mThumbOffsetX = mThumbOffsetY = 0;
533 mNotifiedWindows = null;
534 }
535
536 void register() {
537 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
538 if (mClientChannel != null) {
539 Slog.e(TAG, "Duplicate register of drag input channel");
540 } else {
541 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
542 mServerChannel = channels[0];
543 mClientChannel = channels[1];
544 mInputManager.registerInputChannel(mServerChannel);
545 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
546 mH.getLooper().getQueue());
547 }
548 }
549
550 void unregister() {
551 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
552 if (mClientChannel == null) {
553 Slog.e(TAG, "Unregister of nonexistent drag input channel");
554 } else {
555 mInputManager.unregisterInputChannel(mServerChannel);
556 InputQueue.unregisterInputChannel(mClientChannel);
557 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700558 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700559 mClientChannel = null;
560 mServerChannel = null;
561 }
562 }
563
Chris Tatea32dcf72010-10-14 12:13:50 -0700564 int getDragLayerLw() {
565 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
566 * TYPE_LAYER_MULTIPLIER
567 + TYPE_LAYER_OFFSET;
568 }
569
Christopher Tatea53146c2010-09-07 11:57:52 -0700570 /* call out to each visible window/session informing it about the drag
571 */
Chris Tateb8203e92010-10-12 14:23:21 -0700572 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700573 // Cache a base-class instance of the clip metadata so that parceling
574 // works correctly in calling out to the apps.
Dianne Hackbornf834dfa2010-10-26 12:43:57 -0700575 mDataDescription = mData.getDescription();
Christopher Tatea53146c2010-09-07 11:57:52 -0700576 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700577 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700578
579 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700580 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700581 }
582
Christopher Tate2c095f32010-10-04 14:13:40 -0700583 final int N = mWindows.size();
584 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700585 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700586 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700587 }
588
589 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
590 * designated window is potentially a drop recipient. There are race situations
591 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
592 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700593 *
594 * This method clones the 'event' parameter if it's being delivered to the same
595 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700596 */
Chris Tateb478f462010-10-15 16:02:26 -0700597 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
598 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700599 // Don't actually send the event if the drag is supposed to be pinned
600 // to the originating window but 'newWin' is not that window.
601 if (mLocalOnly) {
602 final IBinder winBinder = newWin.mClient.asBinder();
603 if (winBinder != mLocalWin) {
604 if (DEBUG_DRAG) {
605 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
606 }
607 return;
608 }
609 }
610
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700611 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700612 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
613 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700614 desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700615 try {
616 newWin.mClient.dispatchDragEvent(event);
617 // track each window that we've notified that the drag is starting
618 mNotifiedWindows.add(newWin);
619 } catch (RemoteException e) {
620 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700621 } finally {
622 // if the callee was local, the dispatch has already recycled the event
623 if (Process.myPid() != newWin.mSession.mPid) {
624 event.recycle();
625 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700626 }
627 }
628 }
629
630 /* helper - construct and send a DRAG_STARTED event only if the window has not
631 * previously been notified, i.e. it became visible after the drag operation
632 * was begun. This is a rare case.
633 */
634 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700635 if (mDragInProgress) {
636 // If we have sent the drag-started, we needn't do so again
637 for (WindowState ws : mNotifiedWindows) {
638 if (ws == newWin) {
639 return;
640 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700641 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700642 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700643 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700644 }
Chris Tateb478f462010-10-15 16:02:26 -0700645 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700646 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700647 }
648
Chris Tated4533f142010-10-19 15:15:08 -0700649 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700650 if (DEBUG_DRAG) {
651 Slog.d(TAG, "broadcasting DRAG_ENDED");
652 }
Chris Tated4533f142010-10-19 15:15:08 -0700653 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
654 0, 0, null, null, mDragResult);
655 for (WindowState ws: mNotifiedWindows) {
656 try {
657 ws.mClient.dispatchDragEvent(evt);
658 } catch (RemoteException e) {
659 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700660 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700661 }
Chris Tated4533f142010-10-19 15:15:08 -0700662 mNotifiedWindows.clear();
663 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700664 evt.recycle();
665 }
666
Chris Tated4533f142010-10-19 15:15:08 -0700667 void endDragLw() {
668 mDragState.broadcastDragEndedLw();
669
670 // stop intercepting input
671 mDragState.unregister();
672 mInputMonitor.updateInputWindowsLw();
673
674 // free our resources and drop all the object references
675 mDragState.reset();
676 mDragState = null;
677 }
678
Christopher Tatea53146c2010-09-07 11:57:52 -0700679 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700680 final int myPid = Process.myPid();
681
682 // Move the surface to the given touch
683 mSurface.openTransaction();
684 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
685 mSurface.closeTransaction();
686
687 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700688 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tate7b362e42010-11-04 16:02:52 -0700689 if (mLocalOnly) {
690 final IBinder touchedBinder = touchedWin.mClient.asBinder();
691 if (touchedBinder != mLocalWin) {
692 // This drag is pinned only to the originating window, but the drag
693 // point is outside that window. Pretend it's over empty space.
694 touchedWin = null;
695 }
696 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700697 try {
698 // have we dragged over a new window?
699 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
700 if (DEBUG_DRAG) {
701 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
702 }
703 // force DRAG_EXITED_EVENT if appropriate
704 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700705 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700706 null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700707 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700708 if (myPid != mTargetWindow.mSession.mPid) {
709 evt.recycle();
710 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700711 }
712 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700713 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700714 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
715 }
716 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700717 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700718 null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700719 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700720 if (myPid != touchedWin.mSession.mPid) {
721 evt.recycle();
722 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700723 }
724 } catch (RemoteException e) {
725 Slog.w(TAG, "can't send drag notification to windows");
726 }
727 mTargetWindow = touchedWin;
728 }
729
Chris Tated4533f142010-10-19 15:15:08 -0700730 // Tell the drop target about the data. Returns 'true' if we can immediately
731 // dispatch the global drag-ended message, 'false' if we need to wait for a
732 // result from the recipient.
733 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700734 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700735 if (touchedWin == null) {
736 // "drop" outside a valid window -- no recipient to apply a
737 // timeout to, and we can send the drag-ended message immediately.
738 mDragResult = false;
739 return true;
740 }
741
742 if (DEBUG_DRAG) {
743 Slog.d(TAG, "sending DROP to " + touchedWin);
744 }
745 final int myPid = Process.myPid();
746 final IBinder token = touchedWin.mClient.asBinder();
747 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
748 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
749 null, mData, false);
750 try {
751 touchedWin.mClient.dispatchDragEvent(evt);
752
753 // 5 second timeout for this window to respond to the drop
754 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
755 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
756 mH.sendMessageDelayed(msg, 5000);
757 } catch (RemoteException e) {
758 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
759 return true;
760 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700761 if (myPid != touchedWin.mSession.mPid) {
762 evt.recycle();
763 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700764 }
Chris Tated4533f142010-10-19 15:15:08 -0700765 mToken = token;
766 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700767 }
768
769 // Find the visible, touch-deliverable window under the given point
770 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
771 WindowState touchedWin = null;
772 final int x = (int) xf;
773 final int y = (int) yf;
774 final ArrayList<WindowState> windows = mWindows;
775 final int N = windows.size();
776 for (int i = N - 1; i >= 0; i--) {
777 WindowState child = windows.get(i);
778 final int flags = child.mAttrs.flags;
779 if (!child.isVisibleLw()) {
780 // not visible == don't tell about drags
781 continue;
782 }
783 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
784 // not touchable == don't tell about drags
785 continue;
786 }
787 // account for the window's decor etc
788 tmpRect.set(child.mFrame);
789 if (child.mTouchableInsets == ViewTreeObserver
790 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
791 // The point is inside of the window if it is
792 // inside the frame, AND the content part of that
793 // frame that was given by the application.
794 tmpRect.left += child.mGivenContentInsets.left;
795 tmpRect.top += child.mGivenContentInsets.top;
796 tmpRect.right -= child.mGivenContentInsets.right;
797 tmpRect.bottom -= child.mGivenContentInsets.bottom;
798 } else if (child.mTouchableInsets == ViewTreeObserver
799 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
800 // The point is inside of the window if it is
801 // inside the frame, AND the visible part of that
802 // frame that was given by the application.
803 tmpRect.left += child.mGivenVisibleInsets.left;
804 tmpRect.top += child.mGivenVisibleInsets.top;
805 tmpRect.right -= child.mGivenVisibleInsets.right;
806 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
807 }
808 final int touchFlags = flags &
809 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
810 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
811 if (tmpRect.contains(x, y) || touchFlags == 0) {
812 // Found it
813 touchedWin = child;
814 break;
815 }
816 }
817
818 return touchedWin;
819 }
820 }
821
822 DragState mDragState = null;
823 private final InputHandler mDragInputHandler = new BaseInputHandler() {
824 @Override
825 public void handleMotion(MotionEvent event, Runnable finishedCallback) {
826 boolean endDrag = false;
827 final float newX = event.getRawX();
828 final float newY = event.getRawY();
829
830 try {
831 if (mDragState != null) {
832 switch (event.getAction()) {
833 case MotionEvent.ACTION_DOWN: {
834 if (DEBUG_DRAG) {
835 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
836 }
837 } break;
838
839 case MotionEvent.ACTION_MOVE: {
840 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700841 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700842 mDragState.notifyMoveLw(newX, newY);
843 }
844 } break;
845
846 case MotionEvent.ACTION_UP: {
847 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
848 + newX + "," + newY);
849 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700850 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700851 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700852 } break;
853
854 case MotionEvent.ACTION_CANCEL: {
855 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
856 endDrag = true;
857 } break;
858 }
859
860 if (endDrag) {
861 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
862 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700863 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700864 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700865 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700866 }
867 }
868 } catch (Exception e) {
869 Slog.e(TAG, "Exception caught by drag handleMotion", e);
870 } finally {
871 finishedCallback.run();
872 }
873 }
874 };
875
876 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 * Whether the UI is currently running in touch mode (not showing
878 * navigational focus because the user is directly pressing the screen).
879 */
880 boolean mInTouchMode = false;
881
882 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700883 private ArrayList<WindowChangeListener> mWindowChangeListeners =
884 new ArrayList<WindowChangeListener>();
885 private boolean mWindowsChanged = false;
886
887 public interface WindowChangeListener {
888 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700889 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891
Dianne Hackbornc485a602009-03-24 22:39:49 -0700892 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700893 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700894
895 // The frame use to limit the size of the app running in compatibility mode.
896 Rect mCompatibleScreenFrame = new Rect();
897 // The surface used to fill the outer rim of the app running in compatibility mode.
898 Surface mBackgroundFillerSurface = null;
899 boolean mBackgroundFillerShown = false;
900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 public static WindowManagerService main(Context context,
902 PowerManagerService pm, boolean haveInputMethods) {
903 WMThread thr = new WMThread(context, pm, haveInputMethods);
904 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 synchronized (thr) {
907 while (thr.mService == null) {
908 try {
909 thr.wait();
910 } catch (InterruptedException e) {
911 }
912 }
913 }
Romain Guy06882f82009-06-10 13:36:04 -0700914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 return thr.mService;
916 }
Romain Guy06882f82009-06-10 13:36:04 -0700917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 static class WMThread extends Thread {
919 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 private final Context mContext;
922 private final PowerManagerService mPM;
923 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 public WMThread(Context context, PowerManagerService pm,
926 boolean haveInputMethods) {
927 super("WindowManager");
928 mContext = context;
929 mPM = pm;
930 mHaveInputMethods = haveInputMethods;
931 }
Romain Guy06882f82009-06-10 13:36:04 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 public void run() {
934 Looper.prepare();
935 WindowManagerService s = new WindowManagerService(mContext, mPM,
936 mHaveInputMethods);
937 android.os.Process.setThreadPriority(
938 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700939 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 synchronized (this) {
942 mService = s;
943 notifyAll();
944 }
Romain Guy06882f82009-06-10 13:36:04 -0700945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 Looper.loop();
947 }
948 }
949
950 static class PolicyThread extends Thread {
951 private final WindowManagerPolicy mPolicy;
952 private final WindowManagerService mService;
953 private final Context mContext;
954 private final PowerManagerService mPM;
955 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 public PolicyThread(WindowManagerPolicy policy,
958 WindowManagerService service, Context context,
959 PowerManagerService pm) {
960 super("WindowManagerPolicy");
961 mPolicy = policy;
962 mService = service;
963 mContext = context;
964 mPM = pm;
965 }
Romain Guy06882f82009-06-10 13:36:04 -0700966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 public void run() {
968 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800969 WindowManagerPolicyThread.set(this, Looper.myLooper());
970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800972 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 android.os.Process.setThreadPriority(
974 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700975 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 synchronized (this) {
979 mRunning = true;
980 notifyAll();
981 }
Romain Guy06882f82009-06-10 13:36:04 -0700982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 Looper.loop();
984 }
985 }
986
987 private WindowManagerService(Context context, PowerManagerService pm,
988 boolean haveInputMethods) {
989 mContext = context;
990 mHaveInputMethods = haveInputMethods;
991 mLimitedAlphaCompositing = context.getResources().getBoolean(
992 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 mPowerManager = pm;
995 mPowerManager.setPolicy(mPolicy);
996 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
997 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
998 "SCREEN_FROZEN");
999 mScreenFrozenLock.setReferenceCounted(false);
1000
1001 mActivityManager = ActivityManagerNative.getDefault();
1002 mBatteryStats = BatteryStatsService.getService();
1003
1004 // Get persisted window scale setting
1005 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1006 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1007 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1008 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001009
Jim Miller284b62e2010-06-08 14:27:42 -07001010 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1011 IntentFilter filter = new IntentFilter();
1012 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1013 mContext.registerReceiver(mBroadcastReceiver, filter);
1014
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001015 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1016 "KEEP_SCREEN_ON_FLAG");
1017 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018
Jeff Browne33348b2010-07-15 23:54:05 -07001019 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1022 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 synchronized (thr) {
1025 while (!thr.mRunning) {
1026 try {
1027 thr.wait();
1028 } catch (InterruptedException e) {
1029 }
1030 }
1031 }
Romain Guy06882f82009-06-10 13:36:04 -07001032
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001033 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 // Add ourself to the Watchdog monitors.
1036 Watchdog.getInstance().addMonitor(this);
1037 }
1038
1039 @Override
1040 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1041 throws RemoteException {
1042 try {
1043 return super.onTransact(code, data, reply, flags);
1044 } catch (RuntimeException e) {
1045 // The window manager only throws security exceptions, so let's
1046 // log all others.
1047 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001048 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 }
1050 throw e;
1051 }
1052 }
1053
Jeff Browne33348b2010-07-15 23:54:05 -07001054 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001056 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 TAG, "Adding window " + window + " at "
1058 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1059 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001060 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 }
1062
Jeff Browne33348b2010-07-15 23:54:05 -07001063 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001065 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 TAG, "Adding window " + window + " at "
1067 + i + " of " + mWindows.size() + " (before " + pos + ")");
1068 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001069 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 }
1071
1072 //This method finds out the index of a window that has the same app token as
1073 //win. used for z ordering the windows in mWindows
1074 private int findIdxBasedOnAppTokens(WindowState win) {
1075 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001076 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 int jmax = localmWindows.size();
1078 if(jmax == 0) {
1079 return -1;
1080 }
1081 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001082 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 if(wentry.mAppToken == win.mAppToken) {
1084 return j;
1085 }
1086 }
1087 return -1;
1088 }
Romain Guy06882f82009-06-10 13:36:04 -07001089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1091 final IWindow client = win.mClient;
1092 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001093 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 final int N = localmWindows.size();
1096 final WindowState attached = win.mAttachedWindow;
1097 int i;
1098 if (attached == null) {
1099 int tokenWindowsPos = token.windows.size();
1100 if (token.appWindowToken != null) {
1101 int index = tokenWindowsPos-1;
1102 if (index >= 0) {
1103 // If this application has existing windows, we
1104 // simply place the new window on top of them... but
1105 // keep the starting window on top.
1106 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1107 // Base windows go behind everything else.
1108 placeWindowBefore(token.windows.get(0), win);
1109 tokenWindowsPos = 0;
1110 } else {
1111 AppWindowToken atoken = win.mAppToken;
1112 if (atoken != null &&
1113 token.windows.get(index) == atoken.startingWindow) {
1114 placeWindowBefore(token.windows.get(index), win);
1115 tokenWindowsPos--;
1116 } else {
1117 int newIdx = findIdxBasedOnAppTokens(win);
1118 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001119 //there is a window above this one associated with the same
1120 //apptoken note that the window could be a floating window
1121 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001123 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001124 TAG, "Adding window " + win + " at "
1125 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001127 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 }
1130 }
1131 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001132 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 TAG, "Figuring out where to add app window "
1134 + client.asBinder() + " (token=" + token + ")");
1135 // Figure out where the window should go, based on the
1136 // order of applications.
1137 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001138 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 for (i=NA-1; i>=0; i--) {
1140 AppWindowToken t = mAppTokens.get(i);
1141 if (t == token) {
1142 i--;
1143 break;
1144 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001145
Dianne Hackborna8f60182009-09-01 19:01:50 -07001146 // We haven't reached the token yet; if this token
1147 // is not going to the bottom and has windows, we can
1148 // use it as an anchor for when we do reach the token.
1149 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 pos = t.windows.get(0);
1151 }
1152 }
1153 // We now know the index into the apps. If we found
1154 // an app window above, that gives us the position; else
1155 // we need to look some more.
1156 if (pos != null) {
1157 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001158 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 if (atoken != null) {
1160 final int NC = atoken.windows.size();
1161 if (NC > 0) {
1162 WindowState bottom = atoken.windows.get(0);
1163 if (bottom.mSubLayer < 0) {
1164 pos = bottom;
1165 }
1166 }
1167 }
1168 placeWindowBefore(pos, win);
1169 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001170 // Continue looking down until we find the first
1171 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001172 while (i >= 0) {
1173 AppWindowToken t = mAppTokens.get(i);
1174 final int NW = t.windows.size();
1175 if (NW > 0) {
1176 pos = t.windows.get(NW-1);
1177 break;
1178 }
1179 i--;
1180 }
1181 if (pos != null) {
1182 // Move in front of any windows attached to this
1183 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001184 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 if (atoken != null) {
1186 final int NC = atoken.windows.size();
1187 if (NC > 0) {
1188 WindowState top = atoken.windows.get(NC-1);
1189 if (top.mSubLayer >= 0) {
1190 pos = top;
1191 }
1192 }
1193 }
1194 placeWindowAfter(pos, win);
1195 } else {
1196 // Just search for the start of this layer.
1197 final int myLayer = win.mBaseLayer;
1198 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001199 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (w.mBaseLayer > myLayer) {
1201 break;
1202 }
1203 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001204 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001205 TAG, "Adding window " + win + " at "
1206 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001208 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 }
1210 }
1211 }
1212 } else {
1213 // Figure out where window should go, based on layer.
1214 final int myLayer = win.mBaseLayer;
1215 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001216 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 i++;
1218 break;
1219 }
1220 }
1221 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001222 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001223 TAG, "Adding window " + win + " at "
1224 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001226 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 }
1228 if (addToToken) {
1229 token.windows.add(tokenWindowsPos, win);
1230 }
1231
1232 } else {
1233 // Figure out this window's ordering relative to the window
1234 // it is attached to.
1235 final int NA = token.windows.size();
1236 final int sublayer = win.mSubLayer;
1237 int largestSublayer = Integer.MIN_VALUE;
1238 WindowState windowWithLargestSublayer = null;
1239 for (i=0; i<NA; i++) {
1240 WindowState w = token.windows.get(i);
1241 final int wSublayer = w.mSubLayer;
1242 if (wSublayer >= largestSublayer) {
1243 largestSublayer = wSublayer;
1244 windowWithLargestSublayer = w;
1245 }
1246 if (sublayer < 0) {
1247 // For negative sublayers, we go below all windows
1248 // in the same sublayer.
1249 if (wSublayer >= sublayer) {
1250 if (addToToken) {
1251 token.windows.add(i, win);
1252 }
1253 placeWindowBefore(
1254 wSublayer >= 0 ? attached : w, win);
1255 break;
1256 }
1257 } else {
1258 // For positive sublayers, we go above all windows
1259 // in the same sublayer.
1260 if (wSublayer > sublayer) {
1261 if (addToToken) {
1262 token.windows.add(i, win);
1263 }
1264 placeWindowBefore(w, win);
1265 break;
1266 }
1267 }
1268 }
1269 if (i >= NA) {
1270 if (addToToken) {
1271 token.windows.add(win);
1272 }
1273 if (sublayer < 0) {
1274 placeWindowBefore(attached, win);
1275 } else {
1276 placeWindowAfter(largestSublayer >= 0
1277 ? windowWithLargestSublayer
1278 : attached,
1279 win);
1280 }
1281 }
1282 }
Romain Guy06882f82009-06-10 13:36:04 -07001283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 if (win.mAppToken != null && addToToken) {
1285 win.mAppToken.allAppWindows.add(win);
1286 }
1287 }
Romain Guy06882f82009-06-10 13:36:04 -07001288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 static boolean canBeImeTarget(WindowState w) {
1290 final int fl = w.mAttrs.flags
1291 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1292 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1293 return w.isVisibleOrAdding();
1294 }
1295 return false;
1296 }
Romain Guy06882f82009-06-10 13:36:04 -07001297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001299 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 final int N = localmWindows.size();
1301 WindowState w = null;
1302 int i = N;
1303 while (i > 0) {
1304 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001305 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001306
Joe Onorato8a9b2202010-02-26 18:56:32 -08001307 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 // + Integer.toHexString(w.mAttrs.flags));
1309 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001310 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 // Yet more tricksyness! If this window is a "starting"
1313 // window, we do actually want to be on top of it, but
1314 // it is not -really- where input will go. So if the caller
1315 // is not actually looking to move the IME, look down below
1316 // for a real window to target...
1317 if (!willMove
1318 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1319 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001320 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1322 i--;
1323 w = wb;
1324 }
1325 }
1326 break;
1327 }
1328 }
Romain Guy06882f82009-06-10 13:36:04 -07001329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -07001331
Joe Onorato8a9b2202010-02-26 18:56:32 -08001332 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 if (willMove && w != null) {
1336 final WindowState curTarget = mInputMethodTarget;
1337 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 // Now some fun for dealing with window animations that
1340 // modify the Z order. We need to look at all windows below
1341 // the current target that are in this app, finding the highest
1342 // visible one in layering.
1343 AppWindowToken token = curTarget.mAppToken;
1344 WindowState highestTarget = null;
1345 int highestPos = 0;
1346 if (token.animating || token.animation != null) {
1347 int pos = 0;
1348 pos = localmWindows.indexOf(curTarget);
1349 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001350 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 if (win.mAppToken != token) {
1352 break;
1353 }
1354 if (!win.mRemoved) {
1355 if (highestTarget == null || win.mAnimLayer >
1356 highestTarget.mAnimLayer) {
1357 highestTarget = win;
1358 highestPos = pos;
1359 }
1360 }
1361 pos--;
1362 }
1363 }
Romain Guy06882f82009-06-10 13:36:04 -07001364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001366 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 + mNextAppTransition + " " + highestTarget
1368 + " animating=" + highestTarget.isAnimating()
1369 + " layer=" + highestTarget.mAnimLayer
1370 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001371
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001372 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 // If we are currently setting up for an animation,
1374 // hold everything until we can find out what will happen.
1375 mInputMethodTargetWaitingAnim = true;
1376 mInputMethodTarget = highestTarget;
1377 return highestPos + 1;
1378 } else if (highestTarget.isAnimating() &&
1379 highestTarget.mAnimLayer > w.mAnimLayer) {
1380 // If the window we are currently targeting is involved
1381 // with an animation, and it is on top of the next target
1382 // we will be over, then hold off on moving until
1383 // that is done.
1384 mInputMethodTarget = highestTarget;
1385 return highestPos + 1;
1386 }
1387 }
1388 }
1389 }
Romain Guy06882f82009-06-10 13:36:04 -07001390
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 if (w != null) {
1393 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001394 if (DEBUG_INPUT_METHOD) {
1395 RuntimeException e = null;
1396 if (!HIDE_STACK_CRAWLS) {
1397 e = new RuntimeException();
1398 e.fillInStackTrace();
1399 }
1400 Slog.w(TAG, "Moving IM target from "
1401 + mInputMethodTarget + " to " + w, e);
1402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 mInputMethodTarget = w;
1404 if (w.mAppToken != null) {
1405 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1406 } else {
1407 setInputMethodAnimLayerAdjustment(0);
1408 }
1409 }
1410 return i+1;
1411 }
1412 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001413 if (DEBUG_INPUT_METHOD) {
1414 RuntimeException e = null;
1415 if (!HIDE_STACK_CRAWLS) {
1416 e = new RuntimeException();
1417 e.fillInStackTrace();
1418 }
1419 Slog.w(TAG, "Moving IM target from "
1420 + mInputMethodTarget + " to null", e);
1421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 mInputMethodTarget = null;
1423 setInputMethodAnimLayerAdjustment(0);
1424 }
1425 return -1;
1426 }
Romain Guy06882f82009-06-10 13:36:04 -07001427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 void addInputMethodWindowToListLocked(WindowState win) {
1429 int pos = findDesiredInputMethodWindowIndexLocked(true);
1430 if (pos >= 0) {
1431 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001432 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001433 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001435 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 moveInputMethodDialogsLocked(pos+1);
1437 return;
1438 }
1439 win.mTargetAppToken = null;
1440 addWindowToListInOrderLocked(win, true);
1441 moveInputMethodDialogsLocked(pos);
1442 }
Romain Guy06882f82009-06-10 13:36:04 -07001443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001445 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 mInputMethodAnimLayerAdjustment = adj;
1447 WindowState imw = mInputMethodWindow;
1448 if (imw != null) {
1449 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 + " anim layer: " + imw.mAnimLayer);
1452 int wi = imw.mChildWindows.size();
1453 while (wi > 0) {
1454 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001455 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001457 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 + " anim layer: " + cw.mAnimLayer);
1459 }
1460 }
1461 int di = mInputMethodDialogs.size();
1462 while (di > 0) {
1463 di --;
1464 imw = mInputMethodDialogs.get(di);
1465 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001466 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 + " anim layer: " + imw.mAnimLayer);
1468 }
1469 }
Romain Guy06882f82009-06-10 13:36:04 -07001470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1472 int wpos = mWindows.indexOf(win);
1473 if (wpos >= 0) {
1474 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001477 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 int NC = win.mChildWindows.size();
1479 while (NC > 0) {
1480 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001481 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 int cpos = mWindows.indexOf(cw);
1483 if (cpos >= 0) {
1484 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001485 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001486 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 mWindows.remove(cpos);
1488 }
1489 }
1490 }
1491 return interestingPos;
1492 }
Romain Guy06882f82009-06-10 13:36:04 -07001493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 private void reAddWindowToListInOrderLocked(WindowState win) {
1495 addWindowToListInOrderLocked(win, false);
1496 // This is a hack to get all of the child windows added as well
1497 // at the right position. Child windows should be rare and
1498 // this case should be rare, so it shouldn't be that big a deal.
1499 int wpos = mWindows.indexOf(win);
1500 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001501 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001502 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001504 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 reAddWindowLocked(wpos, win);
1506 }
1507 }
Romain Guy06882f82009-06-10 13:36:04 -07001508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 void logWindowList(String prefix) {
1510 int N = mWindows.size();
1511 while (N > 0) {
1512 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001513 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 }
1515 }
Romain Guy06882f82009-06-10 13:36:04 -07001516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 void moveInputMethodDialogsLocked(int pos) {
1518 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 for (int i=0; i<N; i++) {
1523 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1524 }
1525 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001526 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 logWindowList(" ");
1528 }
Romain Guy06882f82009-06-10 13:36:04 -07001529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 if (pos >= 0) {
1531 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1532 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001533 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (wp == mInputMethodWindow) {
1535 pos++;
1536 }
1537 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001538 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 for (int i=0; i<N; i++) {
1540 WindowState win = dialogs.get(i);
1541 win.mTargetAppToken = targetAppToken;
1542 pos = reAddWindowLocked(pos, win);
1543 }
1544 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001545 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 logWindowList(" ");
1547 }
1548 return;
1549 }
1550 for (int i=0; i<N; i++) {
1551 WindowState win = dialogs.get(i);
1552 win.mTargetAppToken = null;
1553 reAddWindowToListInOrderLocked(win);
1554 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001555 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 logWindowList(" ");
1557 }
1558 }
1559 }
Romain Guy06882f82009-06-10 13:36:04 -07001560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1562 final WindowState imWin = mInputMethodWindow;
1563 final int DN = mInputMethodDialogs.size();
1564 if (imWin == null && DN == 0) {
1565 return false;
1566 }
Romain Guy06882f82009-06-10 13:36:04 -07001567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1569 if (imPos >= 0) {
1570 // In this case, the input method windows are to be placed
1571 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 // First check to see if the input method windows are already
1574 // located here, and contiguous.
1575 final int N = mWindows.size();
1576 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001577 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 // Figure out the actual input method window that should be
1580 // at the bottom of their stack.
1581 WindowState baseImWin = imWin != null
1582 ? imWin : mInputMethodDialogs.get(0);
1583 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001584 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 if (cw.mSubLayer < 0) baseImWin = cw;
1586 }
Romain Guy06882f82009-06-10 13:36:04 -07001587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 if (firstImWin == baseImWin) {
1589 // The windows haven't moved... but are they still contiguous?
1590 // First find the top IM window.
1591 int pos = imPos+1;
1592 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001593 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 break;
1595 }
1596 pos++;
1597 }
1598 pos++;
1599 // Now there should be no more input method windows above.
1600 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001601 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 break;
1603 }
1604 pos++;
1605 }
1606 if (pos >= N) {
1607 // All is good!
1608 return false;
1609 }
1610 }
Romain Guy06882f82009-06-10 13:36:04 -07001611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 if (imWin != null) {
1613 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001614 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 logWindowList(" ");
1616 }
1617 imPos = tmpRemoveWindowLocked(imPos, imWin);
1618 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001619 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 logWindowList(" ");
1621 }
1622 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1623 reAddWindowLocked(imPos, imWin);
1624 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001625 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 logWindowList(" ");
1627 }
1628 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1629 } else {
1630 moveInputMethodDialogsLocked(imPos);
1631 }
Romain Guy06882f82009-06-10 13:36:04 -07001632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 } else {
1634 // In this case, the input method windows go in a fixed layer,
1635 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001638 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 tmpRemoveWindowLocked(0, imWin);
1640 imWin.mTargetAppToken = null;
1641 reAddWindowToListInOrderLocked(imWin);
1642 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001643 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 logWindowList(" ");
1645 }
1646 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1647 } else {
1648 moveInputMethodDialogsLocked(-1);;
1649 }
Romain Guy06882f82009-06-10 13:36:04 -07001650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 }
Romain Guy06882f82009-06-10 13:36:04 -07001652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 if (needAssignLayers) {
1654 assignLayersLocked();
1655 }
Romain Guy06882f82009-06-10 13:36:04 -07001656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 return true;
1658 }
Romain Guy06882f82009-06-10 13:36:04 -07001659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 void adjustInputMethodDialogsLocked() {
1661 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1662 }
Romain Guy06882f82009-06-10 13:36:04 -07001663
Dianne Hackborn25994b42009-09-04 14:21:19 -07001664 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001666 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1667 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1668 ? wallpaperTarget.mAppToken.animation : null)
1669 + " upper=" + mUpperWallpaperTarget
1670 + " lower=" + mLowerWallpaperTarget);
1671 return (wallpaperTarget != null
1672 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1673 && wallpaperTarget.mAppToken.animation != null)))
1674 || mUpperWallpaperTarget != null
1675 || mLowerWallpaperTarget != null;
1676 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001677
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001678 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1679 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001680
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001681 int adjustWallpaperWindowsLocked() {
1682 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001683
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001684 final int dw = mDisplay.getWidth();
1685 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001686
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001687 // First find top-most window that has asked to be on top of the
1688 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001689 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001690 int N = localmWindows.size();
1691 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001692 WindowState foundW = null;
1693 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001694 WindowState topCurW = null;
1695 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001696 int i = N;
1697 while (i > 0) {
1698 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001699 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001700 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1701 if (topCurW == null) {
1702 topCurW = w;
1703 topCurI = i;
1704 }
1705 continue;
1706 }
1707 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001708 if (w.mAppToken != null) {
1709 // If this window's app token is hidden and not animating,
1710 // it is of no interest to us.
1711 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001712 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001713 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001714 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001715 continue;
1716 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001717 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001718 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001719 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1720 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001721 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001722 && (mWallpaperTarget == w
1723 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001724 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001725 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001726 foundW = w;
1727 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001728 if (w == mWallpaperTarget && ((w.mAppToken != null
1729 && w.mAppToken.animation != null)
1730 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001731 // The current wallpaper target is animating, so we'll
1732 // look behind it for another possible target and figure
1733 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001734 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001735 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001736 continue;
1737 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001738 break;
1739 }
1740 }
1741
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001742 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001743 // If we are currently waiting for an app transition, and either
1744 // the current target or the next target are involved with it,
1745 // then hold off on doing anything with the wallpaper.
1746 // Note that we are checking here for just whether the target
1747 // is part of an app token... which is potentially overly aggressive
1748 // (the app token may not be involved in the transition), but good
1749 // enough (we'll just wait until whatever transition is pending
1750 // executes).
1751 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001752 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001753 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001754 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001755 }
1756 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001757 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001758 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001759 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001760 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001761 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001762
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001763 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001764 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001765 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001766 + " oldTarget: " + mWallpaperTarget);
1767 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001768
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001769 mLowerWallpaperTarget = null;
1770 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001771
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001772 WindowState oldW = mWallpaperTarget;
1773 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001774
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001775 // Now what is happening... if the current and new targets are
1776 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001777 if (foundW != null && oldW != null) {
1778 boolean oldAnim = oldW.mAnimation != null
1779 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1780 boolean foundAnim = foundW.mAnimation != null
1781 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001782 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001784 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001785 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001786 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001787 int oldI = localmWindows.indexOf(oldW);
1788 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001789 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001790 }
1791 if (oldI >= 0) {
1792 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001793 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001794 + "=" + oldW + "; new#" + foundI
1795 + "=" + foundW);
1796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001797
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001798 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001799 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001800 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001801 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001802 }
1803 mWallpaperTarget = oldW;
1804 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001805
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001806 // Now set the upper and lower wallpaper targets
1807 // correctly, and make sure that we are positioning
1808 // the wallpaper below the lower.
1809 if (foundI > oldI) {
1810 // The new target is on top of the old one.
1811 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001812 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001813 }
1814 mUpperWallpaperTarget = foundW;
1815 mLowerWallpaperTarget = oldW;
1816 foundW = oldW;
1817 foundI = oldI;
1818 } else {
1819 // The new target is below the old one.
1820 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001821 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001822 }
1823 mUpperWallpaperTarget = oldW;
1824 mLowerWallpaperTarget = foundW;
1825 }
1826 }
1827 }
1828 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001829
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001830 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001831 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001832 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1833 || (mLowerWallpaperTarget.mAppToken != null
1834 && mLowerWallpaperTarget.mAppToken.animation != null);
1835 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1836 || (mUpperWallpaperTarget.mAppToken != null
1837 && mUpperWallpaperTarget.mAppToken.animation != null);
1838 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001839 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001840 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001841 }
1842 mLowerWallpaperTarget = null;
1843 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001844 }
1845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001846
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001847 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001848 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001849 // The window is visible to the compositor... but is it visible
1850 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001851 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001852 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001853
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001854 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001855 // its layer adjustment. Only do this if we are not transfering
1856 // between two wallpaper targets.
1857 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001858 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001859 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001860
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001861 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1862 * TYPE_LAYER_MULTIPLIER
1863 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001864
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001865 // Now w is the window we are supposed to be behind... but we
1866 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001867 // AND any starting window associated with it, AND below the
1868 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001869 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001870 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001871 if (wb.mBaseLayer < maxLayer &&
1872 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001873 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001874 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001875 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001876 // This window is not related to the previous one in any
1877 // interesting way, so stop here.
1878 break;
1879 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001880 foundW = wb;
1881 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001882 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001883 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001884 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001885 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001886
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001887 if (foundW == null && topCurW != null) {
1888 // There is no wallpaper target, so it goes at the bottom.
1889 // We will assume it is the same place as last time, if known.
1890 foundW = topCurW;
1891 foundI = topCurI+1;
1892 } else {
1893 // Okay i is the position immediately above the wallpaper. Look at
1894 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001895 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001896 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001897
Dianne Hackborn284ac932009-08-28 10:34:25 -07001898 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001899 if (mWallpaperTarget.mWallpaperX >= 0) {
1900 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001901 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001902 }
1903 if (mWallpaperTarget.mWallpaperY >= 0) {
1904 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001905 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001906 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001907 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001908
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001909 // Start stepping backwards from here, ensuring that our wallpaper windows
1910 // are correctly placed.
1911 int curTokenIndex = mWallpaperTokens.size();
1912 while (curTokenIndex > 0) {
1913 curTokenIndex--;
1914 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001915 if (token.hidden == visible) {
1916 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1917 token.hidden = !visible;
1918 // Need to do a layout to ensure the wallpaper now has the
1919 // correct size.
1920 mLayoutNeeded = true;
1921 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001922
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001923 int curWallpaperIndex = token.windows.size();
1924 while (curWallpaperIndex > 0) {
1925 curWallpaperIndex--;
1926 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001927
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001928 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001929 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001930 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001931
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001932 // First, make sure the client has the current visibility
1933 // state.
1934 if (wallpaper.mWallpaperVisible != visible) {
1935 wallpaper.mWallpaperVisible = visible;
1936 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001937 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001938 "Setting visibility of wallpaper " + wallpaper
1939 + ": " + visible);
1940 wallpaper.mClient.dispatchAppVisibility(visible);
1941 } catch (RemoteException e) {
1942 }
1943 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001944
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001945 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001946 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001947 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001948
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001949 // First, if this window is at the current index, then all
1950 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001951 if (wallpaper == foundW) {
1952 foundI--;
1953 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001954 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001955 continue;
1956 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001957
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001958 // The window didn't match... the current wallpaper window,
1959 // wherever it is, is in the wrong place, so make sure it is
1960 // not in the list.
1961 int oldIndex = localmWindows.indexOf(wallpaper);
1962 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001963 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001964 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001965 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001966 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001967 if (oldIndex < foundI) {
1968 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001969 }
1970 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001971
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001972 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001973 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001974 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001975 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001976
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001977 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001978 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001979 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001980 }
1981 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001982
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001983 return changed;
1984 }
1985
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001986 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001987 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001988 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001989 mWallpaperAnimLayerAdjustment = adj;
1990 int curTokenIndex = mWallpaperTokens.size();
1991 while (curTokenIndex > 0) {
1992 curTokenIndex--;
1993 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1994 int curWallpaperIndex = token.windows.size();
1995 while (curWallpaperIndex > 0) {
1996 curWallpaperIndex--;
1997 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1998 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001999 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002000 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002001 }
2002 }
2003 }
2004
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002005 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2006 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002007 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002008 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002009 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002010 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002011 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2012 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2013 changed = wallpaperWin.mXOffset != offset;
2014 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002015 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002016 + wallpaperWin + " x: " + offset);
2017 wallpaperWin.mXOffset = offset;
2018 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002019 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002020 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002021 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002022 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002023 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002024
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002025 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002026 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002027 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2028 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2029 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002030 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002031 + wallpaperWin + " y: " + offset);
2032 changed = true;
2033 wallpaperWin.mYOffset = offset;
2034 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002035 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002036 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002037 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002038 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002039 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002040
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002041 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002042 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002043 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002044 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2045 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002046 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002047 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002048 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002049 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002050 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2051 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002052 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002053 if (mWaitingOnWallpaper != null) {
2054 long start = SystemClock.uptimeMillis();
2055 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2056 < start) {
2057 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002058 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002059 "Waiting for offset complete...");
2060 mWindowMap.wait(WALLPAPER_TIMEOUT);
2061 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002062 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002063 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002064 if ((start+WALLPAPER_TIMEOUT)
2065 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002066 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002067 + wallpaperWin);
2068 mLastWallpaperTimeoutTime = start;
2069 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002070 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002071 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002072 }
2073 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002074 } catch (RemoteException e) {
2075 }
2076 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002077
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002078 return changed;
2079 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002080
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002081 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002082 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002083 if (mWaitingOnWallpaper != null &&
2084 mWaitingOnWallpaper.mClient.asBinder() == window) {
2085 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002086 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002087 }
2088 }
2089 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002090
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002091 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002092 final int dw = mDisplay.getWidth();
2093 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002094
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002095 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002096
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002097 WindowState target = mWallpaperTarget;
2098 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002099 if (target.mWallpaperX >= 0) {
2100 mLastWallpaperX = target.mWallpaperX;
2101 } else if (changingTarget.mWallpaperX >= 0) {
2102 mLastWallpaperX = changingTarget.mWallpaperX;
2103 }
2104 if (target.mWallpaperY >= 0) {
2105 mLastWallpaperY = target.mWallpaperY;
2106 } else if (changingTarget.mWallpaperY >= 0) {
2107 mLastWallpaperY = changingTarget.mWallpaperY;
2108 }
2109 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002110
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002111 int curTokenIndex = mWallpaperTokens.size();
2112 while (curTokenIndex > 0) {
2113 curTokenIndex--;
2114 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2115 int curWallpaperIndex = token.windows.size();
2116 while (curWallpaperIndex > 0) {
2117 curWallpaperIndex--;
2118 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2119 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2120 wallpaper.computeShownFrameLocked();
2121 changed = true;
2122 // We only want to be synchronous with one wallpaper.
2123 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002124 }
2125 }
2126 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002127
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002128 return changed;
2129 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002130
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002131 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002132 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002133 final int dw = mDisplay.getWidth();
2134 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002135
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002136 int curTokenIndex = mWallpaperTokens.size();
2137 while (curTokenIndex > 0) {
2138 curTokenIndex--;
2139 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002140 if (token.hidden == visible) {
2141 token.hidden = !visible;
2142 // Need to do a layout to ensure the wallpaper now has the
2143 // correct size.
2144 mLayoutNeeded = true;
2145 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002146
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002147 int curWallpaperIndex = token.windows.size();
2148 while (curWallpaperIndex > 0) {
2149 curWallpaperIndex--;
2150 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2151 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002152 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002153 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002154
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002155 if (wallpaper.mWallpaperVisible != visible) {
2156 wallpaper.mWallpaperVisible = visible;
2157 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002158 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002159 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002160 + ": " + visible);
2161 wallpaper.mClient.dispatchAppVisibility(visible);
2162 } catch (RemoteException e) {
2163 }
2164 }
2165 }
2166 }
2167 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 public int addWindow(Session session, IWindow client,
2170 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002171 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 int res = mPolicy.checkAddPermission(attrs);
2173 if (res != WindowManagerImpl.ADD_OKAY) {
2174 return res;
2175 }
Romain Guy06882f82009-06-10 13:36:04 -07002176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177 boolean reportNewConfig = false;
2178 WindowState attachedWindow = null;
2179 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002180 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002184 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 }
Romain Guy06882f82009-06-10 13:36:04 -07002186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002188 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2190 }
2191
2192 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002193 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002194 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002195 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 + attrs.token + ". Aborting.");
2197 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2198 }
2199 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2200 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002201 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202 + attrs.token + ". Aborting.");
2203 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2204 }
2205 }
2206
2207 boolean addToken = false;
2208 WindowToken token = mTokenMap.get(attrs.token);
2209 if (token == null) {
2210 if (attrs.type >= FIRST_APPLICATION_WINDOW
2211 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002212 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 + attrs.token + ". Aborting.");
2214 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2215 }
2216 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002217 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 + attrs.token + ". Aborting.");
2219 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2220 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002221 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002222 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002223 + attrs.token + ". Aborting.");
2224 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 token = new WindowToken(attrs.token, -1, false);
2227 addToken = true;
2228 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2229 && attrs.type <= LAST_APPLICATION_WINDOW) {
2230 AppWindowToken atoken = token.appWindowToken;
2231 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002232 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 + token + ". Aborting.");
2234 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2235 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002236 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237 + token + ". Aborting.");
2238 return WindowManagerImpl.ADD_APP_EXITING;
2239 }
2240 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2241 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002242 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2244 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2245 }
2246 } else if (attrs.type == TYPE_INPUT_METHOD) {
2247 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002248 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 + attrs.token + ". Aborting.");
2250 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2251 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002252 } else if (attrs.type == TYPE_WALLPAPER) {
2253 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002254 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002255 + attrs.token + ". Aborting.");
2256 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 }
2259
2260 win = new WindowState(session, client, token,
2261 attachedWindow, attrs, viewVisibility);
2262 if (win.mDeathRecipient == null) {
2263 // Client has apparently died, so there is no reason to
2264 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002265 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 + " that is dead, aborting.");
2267 return WindowManagerImpl.ADD_APP_EXITING;
2268 }
2269
2270 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 res = mPolicy.prepareAddWindowLw(win, attrs);
2273 if (res != WindowManagerImpl.ADD_OKAY) {
2274 return res;
2275 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002276
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002277 if (outInputChannel != null) {
2278 String name = win.makeInputChannelName();
2279 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2280 win.mInputChannel = inputChannels[0];
2281 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2282
2283 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285
2286 // From now on, no exceptions or errors allowed!
2287
2288 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002289
Dianne Hackborn5132b372010-07-29 12:51:35 -07002290 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 if (addToken) {
2293 mTokenMap.put(attrs.token, token);
2294 mTokenList.add(token);
2295 }
2296 win.attach();
2297 mWindowMap.put(client.asBinder(), win);
2298
2299 if (attrs.type == TYPE_APPLICATION_STARTING &&
2300 token.appWindowToken != null) {
2301 token.appWindowToken.startingWindow = win;
2302 }
2303
2304 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 if (attrs.type == TYPE_INPUT_METHOD) {
2307 mInputMethodWindow = win;
2308 addInputMethodWindowToListLocked(win);
2309 imMayMove = false;
2310 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2311 mInputMethodDialogs.add(win);
2312 addWindowToListInOrderLocked(win, true);
2313 adjustInputMethodDialogsLocked();
2314 imMayMove = false;
2315 } else {
2316 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002317 if (attrs.type == TYPE_WALLPAPER) {
2318 mLastWallpaperTimeoutTime = 0;
2319 adjustWallpaperWindowsLocked();
2320 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002321 adjustWallpaperWindowsLocked();
2322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 }
Romain Guy06882f82009-06-10 13:36:04 -07002324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 if (mInTouchMode) {
2330 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2331 }
2332 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2333 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2334 }
Romain Guy06882f82009-06-10 13:36:04 -07002335
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002336 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002337 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002338 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2339 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 imMayMove = false;
2341 }
2342 }
Romain Guy06882f82009-06-10 13:36:04 -07002343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002345 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 }
Romain Guy06882f82009-06-10 13:36:04 -07002347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 assignLayersLocked();
2349 // Don't do layout here, the window must call
2350 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 //dump();
2353
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002354 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002355 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002356 }
Jeff Brown349703e2010-06-22 01:27:15 -07002357
Joe Onorato8a9b2202010-02-26 18:56:32 -08002358 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 TAG, "New client " + client.asBinder()
2360 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002361
2362 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2363 reportNewConfig = true;
2364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 }
2366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (reportNewConfig) {
2368 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 return res;
2374 }
Romain Guy06882f82009-06-10 13:36:04 -07002375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 public void removeWindow(Session session, IWindow client) {
2377 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002378 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 if (win == null) {
2380 return;
2381 }
2382 removeWindowLocked(session, win);
2383 }
2384 }
Romain Guy06882f82009-06-10 13:36:04 -07002385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 public void removeWindowLocked(Session session, WindowState win) {
2387
Joe Onorato8a9b2202010-02-26 18:56:32 -08002388 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 TAG, "Remove " + win + " client="
2390 + Integer.toHexString(System.identityHashCode(
2391 win.mClient.asBinder()))
2392 + ", surface=" + win.mSurface);
2393
2394 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002395
2396 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002397
Joe Onorato8a9b2202010-02-26 18:56:32 -08002398 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2400 + " mExiting=" + win.mExiting
2401 + " isAnimating=" + win.isAnimating()
2402 + " app-animation="
2403 + (win.mAppToken != null ? win.mAppToken.animation : null)
2404 + " inPendingTransaction="
2405 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2406 + " mDisplayFrozen=" + mDisplayFrozen);
2407 // Visibility of the removed window. Will be used later to update orientation later on.
2408 boolean wasVisible = false;
2409 // First, see if we need to run an animation. If we do, we have
2410 // to hold off on removing the window until the animation is done.
2411 // If the display is frozen, just remove immediately, since the
2412 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002413 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 // If we are not currently running the exit animation, we
2415 // need to see about starting one.
2416 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2419 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2420 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2421 }
2422 // Try starting an animation.
2423 if (applyAnimationLocked(win, transit, false)) {
2424 win.mExiting = true;
2425 }
2426 }
2427 if (win.mExiting || win.isAnimating()) {
2428 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002429 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 win.mExiting = true;
2431 win.mRemoveOnExit = true;
2432 mLayoutNeeded = true;
2433 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2434 performLayoutAndPlaceSurfacesLocked();
2435 if (win.mAppToken != null) {
2436 win.mAppToken.updateReportedVisibilityLocked();
2437 }
2438 //dump();
2439 Binder.restoreCallingIdentity(origId);
2440 return;
2441 }
2442 }
2443
2444 removeWindowInnerLocked(session, win);
2445 // Removing a visible window will effect the computed orientation
2446 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002447 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002448 != mForcedAppOrientation
2449 && updateOrientationFromAppTokensLocked()) {
2450 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 }
2452 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2453 Binder.restoreCallingIdentity(origId);
2454 }
Romain Guy06882f82009-06-10 13:36:04 -07002455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 if (mInputMethodTarget == win) {
2460 moveInputMethodWindowsIfNeededLocked(false);
2461 }
Romain Guy06882f82009-06-10 13:36:04 -07002462
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002463 if (false) {
2464 RuntimeException e = new RuntimeException("here");
2465 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002466 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002467 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 mPolicy.removeWindowLw(win);
2470 win.removeLocked();
2471
2472 mWindowMap.remove(win.mClient.asBinder());
2473 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002474 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002475 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476
2477 if (mInputMethodWindow == win) {
2478 mInputMethodWindow = null;
2479 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2480 mInputMethodDialogs.remove(win);
2481 }
Romain Guy06882f82009-06-10 13:36:04 -07002482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 final WindowToken token = win.mToken;
2484 final AppWindowToken atoken = win.mAppToken;
2485 token.windows.remove(win);
2486 if (atoken != null) {
2487 atoken.allAppWindows.remove(win);
2488 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002489 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 TAG, "**** Removing window " + win + ": count="
2491 + token.windows.size());
2492 if (token.windows.size() == 0) {
2493 if (!token.explicit) {
2494 mTokenMap.remove(token.token);
2495 mTokenList.remove(token);
2496 } else if (atoken != null) {
2497 atoken.firstWindowDrawn = false;
2498 }
2499 }
2500
2501 if (atoken != null) {
2502 if (atoken.startingWindow == win) {
2503 atoken.startingWindow = null;
2504 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2505 // If this is the last window and we had requested a starting
2506 // transition window, well there is no point now.
2507 atoken.startingData = null;
2508 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2509 // If this is the last window except for a starting transition
2510 // window, we need to get rid of the starting transition.
2511 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002512 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 + ": no more real windows");
2514 }
2515 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2516 mH.sendMessage(m);
2517 }
2518 }
Romain Guy06882f82009-06-10 13:36:04 -07002519
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002520 if (win.mAttrs.type == TYPE_WALLPAPER) {
2521 mLastWallpaperTimeoutTime = 0;
2522 adjustWallpaperWindowsLocked();
2523 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002524 adjustWallpaperWindowsLocked();
2525 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 if (!mInLayout) {
2528 assignLayersLocked();
2529 mLayoutNeeded = true;
2530 performLayoutAndPlaceSurfacesLocked();
2531 if (win.mAppToken != null) {
2532 win.mAppToken.updateReportedVisibilityLocked();
2533 }
2534 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002535
2536 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 }
2538
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002539 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2540 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2541 + ": " + msg + " / " + w.mAttrs.getTitle();
2542 if (where != null) {
2543 Slog.i(TAG, str, where);
2544 } else {
2545 Slog.i(TAG, str);
2546 }
2547 }
2548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2550 long origId = Binder.clearCallingIdentity();
2551 try {
2552 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002553 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002555 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 Surface.openTransaction();
2557 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002558 if (SHOW_TRANSACTIONS) logSurface(w,
2559 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 w.mSurface.setTransparentRegionHint(region);
2561 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002562 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 Surface.closeTransaction();
2564 }
2565 }
2566 }
2567 } finally {
2568 Binder.restoreCallingIdentity(origId);
2569 }
2570 }
2571
2572 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002573 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002574 Rect visibleInsets) {
2575 long origId = Binder.clearCallingIdentity();
2576 try {
2577 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002578 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002579 if (w != null) {
2580 w.mGivenInsetsPending = false;
2581 w.mGivenContentInsets.set(contentInsets);
2582 w.mGivenVisibleInsets.set(visibleInsets);
2583 w.mTouchableInsets = touchableInsets;
2584 mLayoutNeeded = true;
2585 performLayoutAndPlaceSurfacesLocked();
2586 }
2587 }
2588 } finally {
2589 Binder.restoreCallingIdentity(origId);
2590 }
2591 }
Romain Guy06882f82009-06-10 13:36:04 -07002592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 public void getWindowDisplayFrame(Session session, IWindow client,
2594 Rect outDisplayFrame) {
2595 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002596 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597 if (win == null) {
2598 outDisplayFrame.setEmpty();
2599 return;
2600 }
2601 outDisplayFrame.set(win.mDisplayFrame);
2602 }
2603 }
2604
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002605 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2606 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002607 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2608 window.mWallpaperX = x;
2609 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002610 window.mWallpaperXStep = xStep;
2611 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002612 if (updateWallpaperOffsetLocked(window, true)) {
2613 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002614 }
2615 }
2616 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002617
Dianne Hackborn75804932009-10-20 20:15:20 -07002618 void wallpaperCommandComplete(IBinder window, Bundle result) {
2619 synchronized (mWindowMap) {
2620 if (mWaitingOnWallpaper != null &&
2621 mWaitingOnWallpaper.mClient.asBinder() == window) {
2622 mWaitingOnWallpaper = null;
2623 mWindowMap.notifyAll();
2624 }
2625 }
2626 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002627
Dianne Hackborn75804932009-10-20 20:15:20 -07002628 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2629 String action, int x, int y, int z, Bundle extras, boolean sync) {
2630 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2631 || window == mUpperWallpaperTarget) {
2632 boolean doWait = sync;
2633 int curTokenIndex = mWallpaperTokens.size();
2634 while (curTokenIndex > 0) {
2635 curTokenIndex--;
2636 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2637 int curWallpaperIndex = token.windows.size();
2638 while (curWallpaperIndex > 0) {
2639 curWallpaperIndex--;
2640 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2641 try {
2642 wallpaper.mClient.dispatchWallpaperCommand(action,
2643 x, y, z, extras, sync);
2644 // We only want to be synchronous with one wallpaper.
2645 sync = false;
2646 } catch (RemoteException e) {
2647 }
2648 }
2649 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002650
Dianne Hackborn75804932009-10-20 20:15:20 -07002651 if (doWait) {
2652 // XXX Need to wait for result.
2653 }
2654 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002655
Dianne Hackborn75804932009-10-20 20:15:20 -07002656 return null;
2657 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 public int relayoutWindow(Session session, IWindow client,
2660 WindowManager.LayoutParams attrs, int requestedWidth,
2661 int requestedHeight, int viewVisibility, boolean insetsPending,
2662 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002663 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 boolean displayed = false;
2665 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002666 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002670 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 if (win == null) {
2672 return 0;
2673 }
2674 win.mRequestedWidth = requestedWidth;
2675 win.mRequestedHeight = requestedHeight;
2676
2677 if (attrs != null) {
2678 mPolicy.adjustWindowParamsLw(attrs);
2679 }
Romain Guy06882f82009-06-10 13:36:04 -07002680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 int attrChanges = 0;
2682 int flagChanges = 0;
2683 if (attrs != null) {
2684 flagChanges = win.mAttrs.flags ^= attrs.flags;
2685 attrChanges = win.mAttrs.copyFrom(attrs);
2686 }
2687
Joe Onorato8a9b2202010-02-26 18:56:32 -08002688 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689
2690 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2691 win.mAlpha = attrs.alpha;
2692 }
2693
2694 final boolean scaledWindow =
2695 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2696
2697 if (scaledWindow) {
2698 // requested{Width|Height} Surface's physical size
2699 // attrs.{width|height} Size on screen
2700 win.mHScale = (attrs.width != requestedWidth) ?
2701 (attrs.width / (float)requestedWidth) : 1.0f;
2702 win.mVScale = (attrs.height != requestedHeight) ?
2703 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002704 } else {
2705 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002706 }
2707
2708 boolean imMayMove = (flagChanges&(
2709 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2710 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 boolean focusMayChange = win.mViewVisibility != viewVisibility
2713 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2714 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002715
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002716 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2717 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 win.mRelayoutCalled = true;
2720 final int oldVisibility = win.mViewVisibility;
2721 win.mViewVisibility = viewVisibility;
2722 if (viewVisibility == View.VISIBLE &&
2723 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2724 displayed = !win.isVisibleLw();
2725 if (win.mExiting) {
2726 win.mExiting = false;
2727 win.mAnimation = null;
2728 }
2729 if (win.mDestroying) {
2730 win.mDestroying = false;
2731 mDestroySurface.remove(win);
2732 }
2733 if (oldVisibility == View.GONE) {
2734 win.mEnterAnimationPending = true;
2735 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002736 if (displayed) {
2737 if (win.mSurface != null && !win.mDrawPending
2738 && !win.mCommitDrawPending && !mDisplayFrozen
2739 && mPolicy.isScreenOn()) {
2740 applyEnterAnimationLocked(win);
2741 }
2742 if ((win.mAttrs.flags
2743 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2744 if (DEBUG_VISIBILITY) Slog.v(TAG,
2745 "Relayout window turning screen on: " + win);
2746 win.mTurnOnScreen = true;
2747 }
2748 int diff = 0;
2749 if (win.mConfiguration != mCurConfiguration
2750 && (win.mConfiguration == null
2751 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2752 win.mConfiguration = mCurConfiguration;
2753 if (DEBUG_CONFIGURATION) {
2754 Slog.i(TAG, "Window " + win + " visible with new config: "
2755 + win.mConfiguration + " / 0x"
2756 + Integer.toHexString(diff));
2757 }
2758 outConfig.setTo(mCurConfiguration);
2759 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002761 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2762 // To change the format, we need to re-build the surface.
2763 win.destroySurfaceLocked();
2764 displayed = true;
2765 }
2766 try {
2767 Surface surface = win.createSurfaceLocked();
2768 if (surface != null) {
2769 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002770 win.mReportDestroySurface = false;
2771 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002772 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002773 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002775 // For some reason there isn't a surface. Clear the
2776 // caller's object so they see the same state.
2777 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 }
2779 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002780 mInputMonitor.updateInputWindowsLw();
2781
Joe Onorato8a9b2202010-02-26 18:56:32 -08002782 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002783 + client + " (" + win.mAttrs.getTitle() + ")",
2784 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 Binder.restoreCallingIdentity(origId);
2786 return 0;
2787 }
2788 if (displayed) {
2789 focusMayChange = true;
2790 }
2791 if (win.mAttrs.type == TYPE_INPUT_METHOD
2792 && mInputMethodWindow == null) {
2793 mInputMethodWindow = win;
2794 imMayMove = true;
2795 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002796 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2797 && win.mAppToken != null
2798 && win.mAppToken.startingWindow != null) {
2799 // Special handling of starting window over the base
2800 // window of the app: propagate lock screen flags to it,
2801 // to provide the correct semantics while starting.
2802 final int mask =
2803 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002804 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2805 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002806 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2807 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002809 } else {
2810 win.mEnterAnimationPending = false;
2811 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002812 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002813 + ": mExiting=" + win.mExiting
2814 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 // If we are not currently running the exit animation, we
2816 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002817 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002818 // Try starting an animation; if there isn't one, we
2819 // can destroy the surface right away.
2820 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2821 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2822 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2823 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002824 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002826 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002828 } else if (win.isAnimating()) {
2829 // Currently in a hide animation... turn this into
2830 // an exit.
2831 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002832 } else if (win == mWallpaperTarget) {
2833 // If the wallpaper is currently behind this
2834 // window, we need to change both of them inside
2835 // of a transaction to avoid artifacts.
2836 win.mExiting = true;
2837 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 } else {
2839 if (mInputMethodWindow == win) {
2840 mInputMethodWindow = null;
2841 }
2842 win.destroySurfaceLocked();
2843 }
2844 }
2845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002846
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002847 if (win.mSurface == null || (win.getAttrs().flags
2848 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2849 || win.mSurfacePendingDestroy) {
2850 // We are being called from a local process, which
2851 // means outSurface holds its current surface. Ensure the
2852 // surface object is cleared, but we don't want it actually
2853 // destroyed at this point.
2854 win.mSurfacePendingDestroy = false;
2855 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002856 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002857 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002858 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002859 "Keeping surface, will report destroy: " + win);
2860 win.mReportDestroySurface = true;
2861 outSurface.copyFrom(win.mSurface);
2862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002863 }
2864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 if (focusMayChange) {
2866 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2867 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 imMayMove = false;
2869 }
2870 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2871 }
Romain Guy06882f82009-06-10 13:36:04 -07002872
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002873 // updateFocusedWindowLocked() already assigned layers so we only need to
2874 // reassign them at this point if the IM window state gets shuffled
2875 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002877 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002878 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2879 // Little hack here -- we -should- be able to rely on the
2880 // function to return true if the IME has moved and needs
2881 // its layer recomputed. However, if the IME was hidden
2882 // and isn't actually moved in the list, its layer may be
2883 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002884 assignLayers = true;
2885 }
2886 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002887 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002888 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002889 assignLayers = true;
2890 }
2891 }
Romain Guy06882f82009-06-10 13:36:04 -07002892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 mLayoutNeeded = true;
2894 win.mGivenInsetsPending = insetsPending;
2895 if (assignLayers) {
2896 assignLayersLocked();
2897 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002898 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002900 if (displayed && win.mIsWallpaper) {
2901 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002902 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002903 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002904 if (win.mAppToken != null) {
2905 win.mAppToken.updateReportedVisibilityLocked();
2906 }
2907 outFrame.set(win.mFrame);
2908 outContentInsets.set(win.mContentInsets);
2909 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002910 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002912 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002913 + ", requestedHeight=" + requestedHeight
2914 + ", viewVisibility=" + viewVisibility
2915 + "\nRelayout returning frame=" + outFrame
2916 + ", surface=" + outSurface);
2917
Joe Onorato8a9b2202010-02-26 18:56:32 -08002918 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2920
2921 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002922
2923 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
2925
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002926 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 sendNewConfiguration();
2928 }
Romain Guy06882f82009-06-10 13:36:04 -07002929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002932 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2933 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2934 }
2935
2936 public void finishDrawingWindow(Session session, IWindow client) {
2937 final long origId = Binder.clearCallingIdentity();
2938 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002939 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002941 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2942 adjustWallpaperWindowsLocked();
2943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002944 mLayoutNeeded = true;
2945 performLayoutAndPlaceSurfacesLocked();
2946 }
2947 }
2948 Binder.restoreCallingIdentity(origId);
2949 }
2950
2951 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002952 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002953 + (lp != null ? lp.packageName : null)
2954 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2955 if (lp != null && lp.windowAnimations != 0) {
2956 // If this is a system resource, don't try to load it from the
2957 // application resources. It is nice to avoid loading application
2958 // resources if we can.
2959 String packageName = lp.packageName != null ? lp.packageName : "android";
2960 int resId = lp.windowAnimations;
2961 if ((resId&0xFF000000) == 0x01000000) {
2962 packageName = "android";
2963 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002964 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 + packageName);
2966 return AttributeCache.instance().get(packageName, resId,
2967 com.android.internal.R.styleable.WindowAnimation);
2968 }
2969 return null;
2970 }
Romain Guy06882f82009-06-10 13:36:04 -07002971
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002972 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002973 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002974 + packageName + " resId=0x" + Integer.toHexString(resId));
2975 if (packageName != null) {
2976 if ((resId&0xFF000000) == 0x01000000) {
2977 packageName = "android";
2978 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002979 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002980 + packageName);
2981 return AttributeCache.instance().get(packageName, resId,
2982 com.android.internal.R.styleable.WindowAnimation);
2983 }
2984 return null;
2985 }
2986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 private void applyEnterAnimationLocked(WindowState win) {
2988 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2989 if (win.mEnterAnimationPending) {
2990 win.mEnterAnimationPending = false;
2991 transit = WindowManagerPolicy.TRANSIT_ENTER;
2992 }
2993
2994 applyAnimationLocked(win, transit, true);
2995 }
2996
2997 private boolean applyAnimationLocked(WindowState win,
2998 int transit, boolean isEntrance) {
2999 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3000 // If we are trying to apply an animation, but already running
3001 // an animation of the same type, then just leave that one alone.
3002 return true;
3003 }
Romain Guy06882f82009-06-10 13:36:04 -07003004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 // Only apply an animation if the display isn't frozen. If it is
3006 // frozen, there is no reason to animate and it can cause strange
3007 // artifacts when we unfreeze the display if some different animation
3008 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003009 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003010 int anim = mPolicy.selectAnimationLw(win, transit);
3011 int attr = -1;
3012 Animation a = null;
3013 if (anim != 0) {
3014 a = AnimationUtils.loadAnimation(mContext, anim);
3015 } else {
3016 switch (transit) {
3017 case WindowManagerPolicy.TRANSIT_ENTER:
3018 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3019 break;
3020 case WindowManagerPolicy.TRANSIT_EXIT:
3021 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3022 break;
3023 case WindowManagerPolicy.TRANSIT_SHOW:
3024 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3025 break;
3026 case WindowManagerPolicy.TRANSIT_HIDE:
3027 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3028 break;
3029 }
3030 if (attr >= 0) {
3031 a = loadAnimation(win.mAttrs, attr);
3032 }
3033 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003034 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3036 + " mAnimation=" + win.mAnimation
3037 + " isEntrance=" + isEntrance);
3038 if (a != null) {
3039 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003040 RuntimeException e = null;
3041 if (!HIDE_STACK_CRAWLS) {
3042 e = new RuntimeException();
3043 e.fillInStackTrace();
3044 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003045 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 }
3047 win.setAnimation(a);
3048 win.mAnimationIsEntrance = isEntrance;
3049 }
3050 } else {
3051 win.clearAnimation();
3052 }
3053
3054 return win.mAnimation != null;
3055 }
3056
3057 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3058 int anim = 0;
3059 Context context = mContext;
3060 if (animAttr >= 0) {
3061 AttributeCache.Entry ent = getCachedAnimations(lp);
3062 if (ent != null) {
3063 context = ent.context;
3064 anim = ent.array.getResourceId(animAttr, 0);
3065 }
3066 }
3067 if (anim != 0) {
3068 return AnimationUtils.loadAnimation(context, anim);
3069 }
3070 return null;
3071 }
Romain Guy06882f82009-06-10 13:36:04 -07003072
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003073 private Animation loadAnimation(String packageName, int resId) {
3074 int anim = 0;
3075 Context context = mContext;
3076 if (resId >= 0) {
3077 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3078 if (ent != null) {
3079 context = ent.context;
3080 anim = resId;
3081 }
3082 }
3083 if (anim != 0) {
3084 return AnimationUtils.loadAnimation(context, anim);
3085 }
3086 return null;
3087 }
3088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 private boolean applyAnimationLocked(AppWindowToken wtoken,
3090 WindowManager.LayoutParams lp, int transit, boolean enter) {
3091 // Only apply an animation if the display isn't frozen. If it is
3092 // frozen, there is no reason to animate and it can cause strange
3093 // artifacts when we unfreeze the display if some different animation
3094 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003095 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003096 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003097 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003098 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003099 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003100 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003101 } else if (mNextAppTransitionPackage != null) {
3102 a = loadAnimation(mNextAppTransitionPackage, enter ?
3103 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003104 } else {
3105 int animAttr = 0;
3106 switch (transit) {
3107 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3108 animAttr = enter
3109 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3110 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3111 break;
3112 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3113 animAttr = enter
3114 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3115 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3116 break;
3117 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3118 animAttr = enter
3119 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3120 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3121 break;
3122 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3123 animAttr = enter
3124 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3125 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3126 break;
3127 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3128 animAttr = enter
3129 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3130 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3131 break;
3132 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3133 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003134 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003135 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3136 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003137 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003138 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003139 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3140 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003141 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003142 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003143 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003144 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3145 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3146 break;
3147 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3148 animAttr = enter
3149 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3150 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3151 break;
3152 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3153 animAttr = enter
3154 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3155 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003156 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003157 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003158 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003159 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003160 + " anim=" + a
3161 + " animAttr=0x" + Integer.toHexString(animAttr)
3162 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 if (a != null) {
3165 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003166 RuntimeException e = null;
3167 if (!HIDE_STACK_CRAWLS) {
3168 e = new RuntimeException();
3169 e.fillInStackTrace();
3170 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003171 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172 }
3173 wtoken.setAnimation(a);
3174 }
3175 } else {
3176 wtoken.clearAnimation();
3177 }
3178
3179 return wtoken.animation != null;
3180 }
3181
3182 // -------------------------------------------------------------
3183 // Application Window Tokens
3184 // -------------------------------------------------------------
3185
3186 public void validateAppTokens(List tokens) {
3187 int v = tokens.size()-1;
3188 int m = mAppTokens.size()-1;
3189 while (v >= 0 && m >= 0) {
3190 AppWindowToken wtoken = mAppTokens.get(m);
3191 if (wtoken.removed) {
3192 m--;
3193 continue;
3194 }
3195 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003196 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003197 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3198 }
3199 v--;
3200 m--;
3201 }
3202 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003203 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003204 v--;
3205 }
3206 while (m >= 0) {
3207 AppWindowToken wtoken = mAppTokens.get(m);
3208 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003209 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003210 }
3211 m--;
3212 }
3213 }
3214
3215 boolean checkCallingPermission(String permission, String func) {
3216 // Quick check: if the calling permission is me, it's all okay.
3217 if (Binder.getCallingPid() == Process.myPid()) {
3218 return true;
3219 }
Romain Guy06882f82009-06-10 13:36:04 -07003220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003221 if (mContext.checkCallingPermission(permission)
3222 == PackageManager.PERMISSION_GRANTED) {
3223 return true;
3224 }
3225 String msg = "Permission Denial: " + func + " from pid="
3226 + Binder.getCallingPid()
3227 + ", uid=" + Binder.getCallingUid()
3228 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003229 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003230 return false;
3231 }
Romain Guy06882f82009-06-10 13:36:04 -07003232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 AppWindowToken findAppWindowToken(IBinder token) {
3234 WindowToken wtoken = mTokenMap.get(token);
3235 if (wtoken == null) {
3236 return null;
3237 }
3238 return wtoken.appWindowToken;
3239 }
Romain Guy06882f82009-06-10 13:36:04 -07003240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 public void addWindowToken(IBinder token, int type) {
3242 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3243 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003244 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003245 }
Romain Guy06882f82009-06-10 13:36:04 -07003246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003247 synchronized(mWindowMap) {
3248 WindowToken wtoken = mTokenMap.get(token);
3249 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003250 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003251 return;
3252 }
3253 wtoken = new WindowToken(token, type, true);
3254 mTokenMap.put(token, wtoken);
3255 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003256 if (type == TYPE_WALLPAPER) {
3257 mWallpaperTokens.add(wtoken);
3258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003259 }
3260 }
Romain Guy06882f82009-06-10 13:36:04 -07003261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003262 public void removeWindowToken(IBinder token) {
3263 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3264 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003265 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003266 }
3267
3268 final long origId = Binder.clearCallingIdentity();
3269 synchronized(mWindowMap) {
3270 WindowToken wtoken = mTokenMap.remove(token);
3271 mTokenList.remove(wtoken);
3272 if (wtoken != null) {
3273 boolean delayed = false;
3274 if (!wtoken.hidden) {
3275 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003277 final int N = wtoken.windows.size();
3278 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 for (int i=0; i<N; i++) {
3281 WindowState win = wtoken.windows.get(i);
3282
3283 if (win.isAnimating()) {
3284 delayed = true;
3285 }
Romain Guy06882f82009-06-10 13:36:04 -07003286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003287 if (win.isVisibleNow()) {
3288 applyAnimationLocked(win,
3289 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 changed = true;
3291 }
3292 }
3293
3294 if (changed) {
3295 mLayoutNeeded = true;
3296 performLayoutAndPlaceSurfacesLocked();
3297 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3298 }
Romain Guy06882f82009-06-10 13:36:04 -07003299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003300 if (delayed) {
3301 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003302 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3303 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304 }
3305 }
Romain Guy06882f82009-06-10 13:36:04 -07003306
Jeff Brownc5ed5912010-07-14 18:48:53 -07003307 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003309 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 }
3311 }
3312 Binder.restoreCallingIdentity(origId);
3313 }
3314
3315 public void addAppToken(int addPos, IApplicationToken token,
3316 int groupId, int requestedOrientation, boolean fullscreen) {
3317 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3318 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003319 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 }
Jeff Brown349703e2010-06-22 01:27:15 -07003321
3322 // Get the dispatching timeout here while we are not holding any locks so that it
3323 // can be cached by the AppWindowToken. The timeout value is used later by the
3324 // input dispatcher in code that does hold locks. If we did not cache the value
3325 // here we would run the chance of introducing a deadlock between the window manager
3326 // (which holds locks while updating the input dispatcher state) and the activity manager
3327 // (which holds locks while querying the application token).
3328 long inputDispatchingTimeoutNanos;
3329 try {
3330 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3331 } catch (RemoteException ex) {
3332 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3333 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3334 }
Romain Guy06882f82009-06-10 13:36:04 -07003335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 synchronized(mWindowMap) {
3337 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3338 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003339 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003340 return;
3341 }
3342 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003343 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 wtoken.groupId = groupId;
3345 wtoken.appFullscreen = fullscreen;
3346 wtoken.requestedOrientation = requestedOrientation;
3347 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003348 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 mTokenMap.put(token.asBinder(), wtoken);
3350 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 // Application tokens start out hidden.
3353 wtoken.hidden = true;
3354 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 //dump();
3357 }
3358 }
Romain Guy06882f82009-06-10 13:36:04 -07003359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 public void setAppGroupId(IBinder token, int groupId) {
3361 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3362 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003363 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003364 }
3365
3366 synchronized(mWindowMap) {
3367 AppWindowToken wtoken = findAppWindowToken(token);
3368 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003369 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003370 return;
3371 }
3372 wtoken.groupId = groupId;
3373 }
3374 }
Romain Guy06882f82009-06-10 13:36:04 -07003375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 public int getOrientationFromWindowsLocked() {
3377 int pos = mWindows.size() - 1;
3378 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003379 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 pos--;
3381 if (wtoken.mAppToken != null) {
3382 // We hit an application window. so the orientation will be determined by the
3383 // app window. No point in continuing further.
3384 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3385 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003386 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 continue;
3388 }
3389 int req = wtoken.mAttrs.screenOrientation;
3390 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3391 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3392 continue;
3393 } else {
3394 return req;
3395 }
3396 }
3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3398 }
Romain Guy06882f82009-06-10 13:36:04 -07003399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003401 int pos = mAppTokens.size() - 1;
3402 int curGroup = 0;
3403 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3404 boolean findingBehind = false;
3405 boolean haveGroup = false;
3406 boolean lastFullscreen = false;
3407 while (pos >= 0) {
3408 AppWindowToken wtoken = mAppTokens.get(pos);
3409 pos--;
3410 // if we're about to tear down this window and not seek for
3411 // the behind activity, don't use it for orientation
3412 if (!findingBehind
3413 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3414 continue;
3415 }
3416
3417 if (!haveGroup) {
3418 // We ignore any hidden applications on the top.
3419 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003420 continue;
3421 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003422 haveGroup = true;
3423 curGroup = wtoken.groupId;
3424 lastOrientation = wtoken.requestedOrientation;
3425 } else if (curGroup != wtoken.groupId) {
3426 // If we have hit a new application group, and the bottom
3427 // of the previous group didn't explicitly say to use
3428 // the orientation behind it, and the last app was
3429 // full screen, then we'll stick with the
3430 // user's orientation.
3431 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3432 && lastFullscreen) {
3433 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003436 int or = wtoken.requestedOrientation;
3437 // If this application is fullscreen, and didn't explicitly say
3438 // to use the orientation behind it, then just take whatever
3439 // orientation it has and ignores whatever is under it.
3440 lastFullscreen = wtoken.appFullscreen;
3441 if (lastFullscreen
3442 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3443 return or;
3444 }
3445 // If this application has requested an explicit orientation,
3446 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003447 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3448 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003449 return or;
3450 }
3451 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3452 }
3453 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 }
Romain Guy06882f82009-06-10 13:36:04 -07003455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003457 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003458 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3459 "updateOrientationFromAppTokens()")) {
3460 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3461 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003462
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003463 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003465
3466 synchronized(mWindowMap) {
3467 if (updateOrientationFromAppTokensLocked()) {
3468 if (freezeThisOneIfNeeded != null) {
3469 AppWindowToken wtoken = findAppWindowToken(
3470 freezeThisOneIfNeeded);
3471 if (wtoken != null) {
3472 startAppFreezingScreenLocked(wtoken,
3473 ActivityInfo.CONFIG_ORIENTATION);
3474 }
3475 }
3476 config = computeNewConfigurationLocked();
3477
3478 } else if (currentConfig != null) {
3479 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003480 // state mismatches the activity manager's, update it,
3481 // disregarding font scale, which should remain set to
3482 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003483 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003484 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003485 if (computeNewConfigurationLocked(mTempConfiguration)) {
3486 if (currentConfig.diff(mTempConfiguration) != 0) {
3487 mWaitingForConfig = true;
3488 mLayoutNeeded = true;
3489 startFreezingDisplayLocked();
3490 config = new Configuration(mTempConfiguration);
3491 }
3492 }
3493 }
3494 }
3495
Dianne Hackborncfaef692009-06-15 14:24:44 -07003496 Binder.restoreCallingIdentity(ident);
3497 return config;
3498 }
3499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003501 * Determine the new desired orientation of the display, returning
3502 * a non-null new Configuration if it has changed from the current
3503 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3504 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3505 * SCREEN. This will typically be done for you if you call
3506 * sendNewConfiguration().
3507 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003508 * The orientation is computed from non-application windows first. If none of
3509 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003510 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3512 * android.os.IBinder)
3513 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003514 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003515 if (mDisplayFrozen) {
3516 // If the display is frozen, some activities may be in the middle
3517 // of restarting, and thus have removed their old window. If the
3518 // window has the flag to hide the lock screen, then the lock screen
3519 // can re-appear and inflict its own orientation on us. Keep the
3520 // orientation stable until this all settles down.
3521 return false;
3522 }
3523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 long ident = Binder.clearCallingIdentity();
3526 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003527 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 mForcedAppOrientation = req;
3531 //send a message to Policy indicating orientation change to take
3532 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003533 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003534 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3535 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3536 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 }
3538 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003539
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003540 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 } finally {
3542 Binder.restoreCallingIdentity(ident);
3543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 }
Romain Guy06882f82009-06-10 13:36:04 -07003545
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003546 int computeForcedAppOrientationLocked() {
3547 int req = getOrientationFromWindowsLocked();
3548 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3549 req = getOrientationFromAppTokensLocked();
3550 }
3551 return req;
3552 }
Romain Guy06882f82009-06-10 13:36:04 -07003553
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003554 public void setNewConfiguration(Configuration config) {
3555 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3556 "setNewConfiguration()")) {
3557 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3558 }
3559
3560 synchronized(mWindowMap) {
3561 mCurConfiguration = new Configuration(config);
3562 mWaitingForConfig = false;
3563 performLayoutAndPlaceSurfacesLocked();
3564 }
3565 }
3566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3568 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3569 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003570 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 }
Romain Guy06882f82009-06-10 13:36:04 -07003572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 synchronized(mWindowMap) {
3574 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3575 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003576 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003577 return;
3578 }
Romain Guy06882f82009-06-10 13:36:04 -07003579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 wtoken.requestedOrientation = requestedOrientation;
3581 }
3582 }
Romain Guy06882f82009-06-10 13:36:04 -07003583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 public int getAppOrientation(IApplicationToken token) {
3585 synchronized(mWindowMap) {
3586 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3587 if (wtoken == null) {
3588 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3589 }
Romain Guy06882f82009-06-10 13:36:04 -07003590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 return wtoken.requestedOrientation;
3592 }
3593 }
Romain Guy06882f82009-06-10 13:36:04 -07003594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3596 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3597 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003598 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 }
3600
3601 synchronized(mWindowMap) {
3602 boolean changed = false;
3603 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003604 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 changed = mFocusedApp != null;
3606 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003607 if (changed) {
3608 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003609 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 } else {
3611 AppWindowToken newFocus = findAppWindowToken(token);
3612 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003613 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 return;
3615 }
3616 changed = mFocusedApp != newFocus;
3617 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003618 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003619 if (changed) {
3620 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 }
3623
3624 if (moveFocusNow && changed) {
3625 final long origId = Binder.clearCallingIdentity();
3626 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3627 Binder.restoreCallingIdentity(origId);
3628 }
3629 }
3630 }
3631
3632 public void prepareAppTransition(int transit) {
3633 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3634 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003635 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 }
Romain Guy06882f82009-06-10 13:36:04 -07003637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003639 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 TAG, "Prepare app transition: transit=" + transit
3641 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003642 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003643 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3644 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003646 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3647 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3648 // Opening a new task always supersedes a close for the anim.
3649 mNextAppTransition = transit;
3650 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3651 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3652 // Opening a new activity always supersedes a close for the anim.
3653 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 }
3655 mAppTransitionReady = false;
3656 mAppTransitionTimeout = false;
3657 mStartingIconInTransition = false;
3658 mSkipAppTransitionAnimation = false;
3659 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3660 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3661 5000);
3662 }
3663 }
3664 }
3665
3666 public int getPendingAppTransition() {
3667 return mNextAppTransition;
3668 }
Romain Guy06882f82009-06-10 13:36:04 -07003669
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003670 public void overridePendingAppTransition(String packageName,
3671 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003672 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003673 mNextAppTransitionPackage = packageName;
3674 mNextAppTransitionEnter = enterAnim;
3675 mNextAppTransitionExit = exitAnim;
3676 }
3677 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 public void executeAppTransition() {
3680 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3681 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003682 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 }
Romain Guy06882f82009-06-10 13:36:04 -07003684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003686 if (DEBUG_APP_TRANSITIONS) {
3687 RuntimeException e = new RuntimeException("here");
3688 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003689 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003690 + mNextAppTransition, e);
3691 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003692 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 mAppTransitionReady = true;
3694 final long origId = Binder.clearCallingIdentity();
3695 performLayoutAndPlaceSurfacesLocked();
3696 Binder.restoreCallingIdentity(origId);
3697 }
3698 }
3699 }
3700
3701 public void setAppStartingWindow(IBinder token, String pkg,
3702 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3703 IBinder transferFrom, boolean createIfNeeded) {
3704 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3705 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003706 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 }
3708
3709 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003710 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3712 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 AppWindowToken wtoken = findAppWindowToken(token);
3715 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003716 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 return;
3718 }
3719
3720 // If the display is frozen, we won't do anything until the
3721 // actual window is displayed so there is no reason to put in
3722 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003723 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 return;
3725 }
Romain Guy06882f82009-06-10 13:36:04 -07003726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 if (wtoken.startingData != null) {
3728 return;
3729 }
Romain Guy06882f82009-06-10 13:36:04 -07003730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 if (transferFrom != null) {
3732 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3733 if (ttoken != null) {
3734 WindowState startingWindow = ttoken.startingWindow;
3735 if (startingWindow != null) {
3736 if (mStartingIconInTransition) {
3737 // In this case, the starting icon has already
3738 // been displayed, so start letting windows get
3739 // shown immediately without any more transitions.
3740 mSkipAppTransitionAnimation = true;
3741 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003742 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 "Moving existing starting from " + ttoken
3744 + " to " + wtoken);
3745 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 // Transfer the starting window over to the new
3748 // token.
3749 wtoken.startingData = ttoken.startingData;
3750 wtoken.startingView = ttoken.startingView;
3751 wtoken.startingWindow = startingWindow;
3752 ttoken.startingData = null;
3753 ttoken.startingView = null;
3754 ttoken.startingWindow = null;
3755 ttoken.startingMoved = true;
3756 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003757 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003759 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003760 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003762 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 ttoken.windows.remove(startingWindow);
3764 ttoken.allAppWindows.remove(startingWindow);
3765 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 // Propagate other interesting state between the
3768 // tokens. If the old token is displayed, we should
3769 // immediately force the new one to be displayed. If
3770 // it is animating, we need to move that animation to
3771 // the new one.
3772 if (ttoken.allDrawn) {
3773 wtoken.allDrawn = true;
3774 }
3775 if (ttoken.firstWindowDrawn) {
3776 wtoken.firstWindowDrawn = true;
3777 }
3778 if (!ttoken.hidden) {
3779 wtoken.hidden = false;
3780 wtoken.hiddenRequested = false;
3781 wtoken.willBeHidden = false;
3782 }
3783 if (wtoken.clientHidden != ttoken.clientHidden) {
3784 wtoken.clientHidden = ttoken.clientHidden;
3785 wtoken.sendAppVisibilityToClients();
3786 }
3787 if (ttoken.animation != null) {
3788 wtoken.animation = ttoken.animation;
3789 wtoken.animating = ttoken.animating;
3790 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3791 ttoken.animation = null;
3792 ttoken.animLayerAdjustment = 0;
3793 wtoken.updateLayers();
3794 ttoken.updateLayers();
3795 }
Romain Guy06882f82009-06-10 13:36:04 -07003796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 mLayoutNeeded = true;
3799 performLayoutAndPlaceSurfacesLocked();
3800 Binder.restoreCallingIdentity(origId);
3801 return;
3802 } else if (ttoken.startingData != null) {
3803 // The previous app was getting ready to show a
3804 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003805 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 "Moving pending starting from " + ttoken
3807 + " to " + wtoken);
3808 wtoken.startingData = ttoken.startingData;
3809 ttoken.startingData = null;
3810 ttoken.startingMoved = true;
3811 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3812 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3813 // want to process the message ASAP, before any other queued
3814 // messages.
3815 mH.sendMessageAtFrontOfQueue(m);
3816 return;
3817 }
3818 }
3819 }
3820
3821 // There is no existing starting window, and the caller doesn't
3822 // want us to create one, so that's it!
3823 if (!createIfNeeded) {
3824 return;
3825 }
Romain Guy06882f82009-06-10 13:36:04 -07003826
Dianne Hackborn284ac932009-08-28 10:34:25 -07003827 // If this is a translucent or wallpaper window, then don't
3828 // show a starting window -- the current effect (a full-screen
3829 // opaque starting window that fades away to the real contents
3830 // when it is ready) does not work for this.
3831 if (theme != 0) {
3832 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3833 com.android.internal.R.styleable.Window);
3834 if (ent.array.getBoolean(
3835 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3836 return;
3837 }
3838 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003839 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3840 return;
3841 }
3842 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003843 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3844 return;
3845 }
3846 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003848 mStartingIconInTransition = true;
3849 wtoken.startingData = new StartingData(
3850 pkg, theme, nonLocalizedLabel,
3851 labelRes, icon);
3852 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3853 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3854 // want to process the message ASAP, before any other queued
3855 // messages.
3856 mH.sendMessageAtFrontOfQueue(m);
3857 }
3858 }
3859
3860 public void setAppWillBeHidden(IBinder token) {
3861 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3862 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003863 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
3865
3866 AppWindowToken wtoken;
3867
3868 synchronized(mWindowMap) {
3869 wtoken = findAppWindowToken(token);
3870 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003871 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 -08003872 return;
3873 }
3874 wtoken.willBeHidden = true;
3875 }
3876 }
Romain Guy06882f82009-06-10 13:36:04 -07003877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3879 boolean visible, int transit, boolean performLayout) {
3880 boolean delayed = false;
3881
3882 if (wtoken.clientHidden == visible) {
3883 wtoken.clientHidden = !visible;
3884 wtoken.sendAppVisibilityToClients();
3885 }
Romain Guy06882f82009-06-10 13:36:04 -07003886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003887 wtoken.willBeHidden = false;
3888 if (wtoken.hidden == visible) {
3889 final int N = wtoken.allAppWindows.size();
3890 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003891 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3893 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003896
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003897 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 if (wtoken.animation == sDummyAnimation) {
3899 wtoken.animation = null;
3900 }
3901 applyAnimationLocked(wtoken, lp, transit, visible);
3902 changed = true;
3903 if (wtoken.animation != null) {
3904 delayed = runningAppAnimation = true;
3905 }
3906 }
Romain Guy06882f82009-06-10 13:36:04 -07003907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003908 for (int i=0; i<N; i++) {
3909 WindowState win = wtoken.allAppWindows.get(i);
3910 if (win == wtoken.startingWindow) {
3911 continue;
3912 }
3913
3914 if (win.isAnimating()) {
3915 delayed = true;
3916 }
Romain Guy06882f82009-06-10 13:36:04 -07003917
Joe Onorato8a9b2202010-02-26 18:56:32 -08003918 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 //win.dump(" ");
3920 if (visible) {
3921 if (!win.isVisibleNow()) {
3922 if (!runningAppAnimation) {
3923 applyAnimationLocked(win,
3924 WindowManagerPolicy.TRANSIT_ENTER, true);
3925 }
3926 changed = true;
3927 }
3928 } else if (win.isVisibleNow()) {
3929 if (!runningAppAnimation) {
3930 applyAnimationLocked(win,
3931 WindowManagerPolicy.TRANSIT_EXIT, false);
3932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 changed = true;
3934 }
3935 }
3936
3937 wtoken.hidden = wtoken.hiddenRequested = !visible;
3938 if (!visible) {
3939 unsetAppFreezingScreenLocked(wtoken, true, true);
3940 } else {
3941 // If we are being set visible, and the starting window is
3942 // not yet displayed, then make sure it doesn't get displayed.
3943 WindowState swin = wtoken.startingWindow;
3944 if (swin != null && (swin.mDrawPending
3945 || swin.mCommitDrawPending)) {
3946 swin.mPolicyVisibility = false;
3947 swin.mPolicyVisibilityAfterAnim = false;
3948 }
3949 }
Romain Guy06882f82009-06-10 13:36:04 -07003950
Joe Onorato8a9b2202010-02-26 18:56:32 -08003951 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3953 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003954
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003955 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003957 if (performLayout) {
3958 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3959 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07003960 } else {
3961 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 }
3964 }
3965
3966 if (wtoken.animation != null) {
3967 delayed = true;
3968 }
Romain Guy06882f82009-06-10 13:36:04 -07003969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 return delayed;
3971 }
3972
3973 public void setAppVisibility(IBinder token, boolean visible) {
3974 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3975 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003976 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 }
3978
3979 AppWindowToken wtoken;
3980
3981 synchronized(mWindowMap) {
3982 wtoken = findAppWindowToken(token);
3983 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003984 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 return;
3986 }
3987
3988 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003989 RuntimeException e = null;
3990 if (!HIDE_STACK_CRAWLS) {
3991 e = new RuntimeException();
3992 e.fillInStackTrace();
3993 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003994 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 + "): mNextAppTransition=" + mNextAppTransition
3996 + " hidden=" + wtoken.hidden
3997 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3998 }
Romain Guy06882f82009-06-10 13:36:04 -07003999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 // If we are preparing an app transition, then delay changing
4001 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004002 if (!mDisplayFrozen && mPolicy.isScreenOn()
4003 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 // Already in requested state, don't do anything more.
4005 if (wtoken.hiddenRequested != visible) {
4006 return;
4007 }
4008 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004009
Joe Onorato8a9b2202010-02-26 18:56:32 -08004010 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 TAG, "Setting dummy animation on: " + wtoken);
4012 wtoken.setDummyAnimation();
4013 mOpeningApps.remove(wtoken);
4014 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004015 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 wtoken.inPendingTransaction = true;
4017 if (visible) {
4018 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 wtoken.startingDisplayed = false;
4020 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004021
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004022 // If the token is currently hidden (should be the
4023 // common case), then we need to set up to wait for
4024 // its windows to be ready.
4025 if (wtoken.hidden) {
4026 wtoken.allDrawn = false;
4027 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004028
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004029 if (wtoken.clientHidden) {
4030 // In the case where we are making an app visible
4031 // but holding off for a transition, we still need
4032 // to tell the client to make its windows visible so
4033 // they get drawn. Otherwise, we will wait on
4034 // performing the transition until all windows have
4035 // been drawn, they never will be, and we are sad.
4036 wtoken.clientHidden = false;
4037 wtoken.sendAppVisibilityToClients();
4038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 }
4040 } else {
4041 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004042
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004043 // If the token is currently visible (should be the
4044 // common case), then set up to wait for it to be hidden.
4045 if (!wtoken.hidden) {
4046 wtoken.waitingToHide = true;
4047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 }
4049 return;
4050 }
Romain Guy06882f82009-06-10 13:36:04 -07004051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004053 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 wtoken.updateReportedVisibilityLocked();
4055 Binder.restoreCallingIdentity(origId);
4056 }
4057 }
4058
4059 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4060 boolean unfreezeSurfaceNow, boolean force) {
4061 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004062 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 + " force=" + force);
4064 final int N = wtoken.allAppWindows.size();
4065 boolean unfrozeWindows = false;
4066 for (int i=0; i<N; i++) {
4067 WindowState w = wtoken.allAppWindows.get(i);
4068 if (w.mAppFreezing) {
4069 w.mAppFreezing = false;
4070 if (w.mSurface != null && !w.mOrientationChanging) {
4071 w.mOrientationChanging = true;
4072 }
4073 unfrozeWindows = true;
4074 }
4075 }
4076 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004077 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 wtoken.freezingScreen = false;
4079 mAppsFreezingScreen--;
4080 }
4081 if (unfreezeSurfaceNow) {
4082 if (unfrozeWindows) {
4083 mLayoutNeeded = true;
4084 performLayoutAndPlaceSurfacesLocked();
4085 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004086 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 }
4088 }
4089 }
Romain Guy06882f82009-06-10 13:36:04 -07004090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4092 int configChanges) {
4093 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004094 RuntimeException e = null;
4095 if (!HIDE_STACK_CRAWLS) {
4096 e = new RuntimeException();
4097 e.fillInStackTrace();
4098 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004099 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 + ": hidden=" + wtoken.hidden + " freezing="
4101 + wtoken.freezingScreen, e);
4102 }
4103 if (!wtoken.hiddenRequested) {
4104 if (!wtoken.freezingScreen) {
4105 wtoken.freezingScreen = true;
4106 mAppsFreezingScreen++;
4107 if (mAppsFreezingScreen == 1) {
4108 startFreezingDisplayLocked();
4109 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4110 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4111 5000);
4112 }
4113 }
4114 final int N = wtoken.allAppWindows.size();
4115 for (int i=0; i<N; i++) {
4116 WindowState w = wtoken.allAppWindows.get(i);
4117 w.mAppFreezing = true;
4118 }
4119 }
4120 }
Romain Guy06882f82009-06-10 13:36:04 -07004121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 public void startAppFreezingScreen(IBinder token, int configChanges) {
4123 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4124 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004125 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 }
4127
4128 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004129 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004130 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004131 return;
4132 }
Romain Guy06882f82009-06-10 13:36:04 -07004133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004134 AppWindowToken wtoken = findAppWindowToken(token);
4135 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004136 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 return;
4138 }
4139 final long origId = Binder.clearCallingIdentity();
4140 startAppFreezingScreenLocked(wtoken, configChanges);
4141 Binder.restoreCallingIdentity(origId);
4142 }
4143 }
Romain Guy06882f82009-06-10 13:36:04 -07004144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 public void stopAppFreezingScreen(IBinder token, boolean force) {
4146 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4147 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004148 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 }
4150
4151 synchronized(mWindowMap) {
4152 AppWindowToken wtoken = findAppWindowToken(token);
4153 if (wtoken == null || wtoken.appToken == null) {
4154 return;
4155 }
4156 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004157 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4159 unsetAppFreezingScreenLocked(wtoken, true, force);
4160 Binder.restoreCallingIdentity(origId);
4161 }
4162 }
Romain Guy06882f82009-06-10 13:36:04 -07004163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 public void removeAppToken(IBinder token) {
4165 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4166 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004167 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 }
4169
4170 AppWindowToken wtoken = null;
4171 AppWindowToken startingToken = null;
4172 boolean delayed = false;
4173
4174 final long origId = Binder.clearCallingIdentity();
4175 synchronized(mWindowMap) {
4176 WindowToken basewtoken = mTokenMap.remove(token);
4177 mTokenList.remove(basewtoken);
4178 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004179 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004180 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 wtoken.inPendingTransaction = false;
4182 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004183 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 if (mClosingApps.contains(wtoken)) {
4185 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004186 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004187 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004188 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 delayed = true;
4190 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004191 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 TAG, "Removing app " + wtoken + " delayed=" + delayed
4193 + " animation=" + wtoken.animation
4194 + " animating=" + wtoken.animating);
4195 if (delayed) {
4196 // set the token aside because it has an active animation to be finished
4197 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004198 } else {
4199 // Make sure there is no animation running on this token,
4200 // so any windows associated with it will be removed as
4201 // soon as their animations are complete
4202 wtoken.animation = null;
4203 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 }
4205 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004206 if (mLastEnterAnimToken == wtoken) {
4207 mLastEnterAnimToken = null;
4208 mLastEnterAnimParams = null;
4209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 wtoken.removed = true;
4211 if (wtoken.startingData != null) {
4212 startingToken = wtoken;
4213 }
4214 unsetAppFreezingScreenLocked(wtoken, true, true);
4215 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004216 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 mFocusedApp = null;
4218 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004219 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 }
4221 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004222 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 }
Romain Guy06882f82009-06-10 13:36:04 -07004224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 if (!delayed && wtoken != null) {
4226 wtoken.updateReportedVisibilityLocked();
4227 }
4228 }
4229 Binder.restoreCallingIdentity(origId);
4230
4231 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004232 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 + startingToken + ": app token removed");
4234 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4235 mH.sendMessage(m);
4236 }
4237 }
4238
4239 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4240 final int NW = token.windows.size();
4241 for (int i=0; i<NW; i++) {
4242 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004243 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004245 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004246 int j = win.mChildWindows.size();
4247 while (j > 0) {
4248 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004249 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004250 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004251 "Tmp removing child window " + cwin);
4252 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 }
4254 }
4255 return NW > 0;
4256 }
4257
4258 void dumpAppTokensLocked() {
4259 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004260 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 }
4262 }
Romain Guy06882f82009-06-10 13:36:04 -07004263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 void dumpWindowsLocked() {
4265 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004266 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 }
4268 }
Romain Guy06882f82009-06-10 13:36:04 -07004269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004270 private int findWindowOffsetLocked(int tokenPos) {
4271 final int NW = mWindows.size();
4272
4273 if (tokenPos >= mAppTokens.size()) {
4274 int i = NW;
4275 while (i > 0) {
4276 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004277 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 if (win.getAppToken() != null) {
4279 return i+1;
4280 }
4281 }
4282 }
4283
4284 while (tokenPos > 0) {
4285 // Find the first app token below the new position that has
4286 // a window displayed.
4287 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004288 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004290 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004291 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004292 "Skipping token -- currently sending to bottom");
4293 tokenPos--;
4294 continue;
4295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 int i = wtoken.windows.size();
4297 while (i > 0) {
4298 i--;
4299 WindowState win = wtoken.windows.get(i);
4300 int j = win.mChildWindows.size();
4301 while (j > 0) {
4302 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004303 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004304 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004305 for (int pos=NW-1; pos>=0; pos--) {
4306 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004307 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 "Found child win @" + (pos+1));
4309 return pos+1;
4310 }
4311 }
4312 }
4313 }
4314 for (int pos=NW-1; pos>=0; pos--) {
4315 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004316 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004317 return pos+1;
4318 }
4319 }
4320 }
4321 tokenPos--;
4322 }
4323
4324 return 0;
4325 }
4326
4327 private final int reAddWindowLocked(int index, WindowState win) {
4328 final int NCW = win.mChildWindows.size();
4329 boolean added = false;
4330 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004331 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004333 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004334 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 mWindows.add(index, win);
4336 index++;
4337 added = true;
4338 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004339 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004340 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 mWindows.add(index, cwin);
4342 index++;
4343 }
4344 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004345 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004346 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 mWindows.add(index, win);
4348 index++;
4349 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004350 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 return index;
4352 }
Romain Guy06882f82009-06-10 13:36:04 -07004353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4355 final int NW = token.windows.size();
4356 for (int i=0; i<NW; i++) {
4357 index = reAddWindowLocked(index, token.windows.get(i));
4358 }
4359 return index;
4360 }
4361
4362 public void moveAppToken(int index, IBinder token) {
4363 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4364 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004365 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 }
4367
4368 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004369 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004370 if (DEBUG_REORDER) dumpAppTokensLocked();
4371 final AppWindowToken wtoken = findAppWindowToken(token);
4372 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004373 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 + token + " (" + wtoken + ")");
4375 return;
4376 }
4377 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004378 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004382 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 if (DEBUG_REORDER) dumpWindowsLocked();
4384 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004385 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 if (DEBUG_REORDER) dumpWindowsLocked();
4387 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004388 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 if (DEBUG_REORDER) dumpWindowsLocked();
4390 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 mLayoutNeeded = true;
4392 performLayoutAndPlaceSurfacesLocked();
4393 }
4394 Binder.restoreCallingIdentity(origId);
4395 }
4396 }
4397
4398 private void removeAppTokensLocked(List<IBinder> tokens) {
4399 // XXX This should be done more efficiently!
4400 // (take advantage of the fact that both lists should be
4401 // ordered in the same way.)
4402 int N = tokens.size();
4403 for (int i=0; i<N; i++) {
4404 IBinder token = tokens.get(i);
4405 final AppWindowToken wtoken = findAppWindowToken(token);
4406 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004407 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 + token + " (" + wtoken + ")");
4409 i--;
4410 N--;
4411 }
4412 }
4413 }
4414
Dianne Hackborna8f60182009-09-01 19:01:50 -07004415 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4416 boolean updateFocusAndLayout) {
4417 // First remove all of the windows from the list.
4418 tmpRemoveAppWindowsLocked(wtoken);
4419
4420 // Where to start adding?
4421 int pos = findWindowOffsetLocked(tokenPos);
4422
4423 // And now add them back at the correct place.
4424 pos = reAddAppWindowsLocked(pos, wtoken);
4425
4426 if (updateFocusAndLayout) {
4427 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4428 assignLayersLocked();
4429 }
4430 mLayoutNeeded = true;
4431 performLayoutAndPlaceSurfacesLocked();
4432 }
4433 }
4434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4436 // First remove all of the windows from the list.
4437 final int N = tokens.size();
4438 int i;
4439 for (i=0; i<N; i++) {
4440 WindowToken token = mTokenMap.get(tokens.get(i));
4441 if (token != null) {
4442 tmpRemoveAppWindowsLocked(token);
4443 }
4444 }
4445
4446 // Where to start adding?
4447 int pos = findWindowOffsetLocked(tokenPos);
4448
4449 // And now add them back at the correct place.
4450 for (i=0; i<N; i++) {
4451 WindowToken token = mTokenMap.get(tokens.get(i));
4452 if (token != null) {
4453 pos = reAddAppWindowsLocked(pos, token);
4454 }
4455 }
4456
Dianne Hackborna8f60182009-09-01 19:01:50 -07004457 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4458 assignLayersLocked();
4459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 mLayoutNeeded = true;
4461 performLayoutAndPlaceSurfacesLocked();
4462
4463 //dump();
4464 }
4465
4466 public void moveAppTokensToTop(List<IBinder> tokens) {
4467 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4468 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004469 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 }
4471
4472 final long origId = Binder.clearCallingIdentity();
4473 synchronized(mWindowMap) {
4474 removeAppTokensLocked(tokens);
4475 final int N = tokens.size();
4476 for (int i=0; i<N; i++) {
4477 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4478 if (wt != null) {
4479 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004480 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004481 mToTopApps.remove(wt);
4482 mToBottomApps.remove(wt);
4483 mToTopApps.add(wt);
4484 wt.sendingToBottom = false;
4485 wt.sendingToTop = true;
4486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004487 }
4488 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004489
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004490 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004491 moveAppWindowsLocked(tokens, mAppTokens.size());
4492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 }
4494 Binder.restoreCallingIdentity(origId);
4495 }
4496
4497 public void moveAppTokensToBottom(List<IBinder> tokens) {
4498 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4499 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004500 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 }
4502
4503 final long origId = Binder.clearCallingIdentity();
4504 synchronized(mWindowMap) {
4505 removeAppTokensLocked(tokens);
4506 final int N = tokens.size();
4507 int pos = 0;
4508 for (int i=0; i<N; i++) {
4509 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4510 if (wt != null) {
4511 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004512 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004513 mToTopApps.remove(wt);
4514 mToBottomApps.remove(wt);
4515 mToBottomApps.add(i, wt);
4516 wt.sendingToTop = false;
4517 wt.sendingToBottom = true;
4518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 pos++;
4520 }
4521 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004522
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004523 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004524 moveAppWindowsLocked(tokens, 0);
4525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 }
4527 Binder.restoreCallingIdentity(origId);
4528 }
4529
4530 // -------------------------------------------------------------
4531 // Misc IWindowSession methods
4532 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004533
Jim Miller284b62e2010-06-08 14:27:42 -07004534 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004535 {
Jim Miller284b62e2010-06-08 14:27:42 -07004536 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4537 // called before DevicePolicyManagerService has started.
4538 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4539 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4540 Context.DEVICE_POLICY_SERVICE);
4541 if (dpm != null) {
4542 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4543 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4544 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4545 }
Jim Millerd6b57052010-06-07 17:52:42 -07004546 }
Jim Miller284b62e2010-06-08 14:27:42 -07004547 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004548 }
4549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004551 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 != PackageManager.PERMISSION_GRANTED) {
4553 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4554 }
Jim Millerd6b57052010-06-07 17:52:42 -07004555
Jim Miller284b62e2010-06-08 14:27:42 -07004556 synchronized (mKeyguardTokenWatcher) {
4557 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 }
4560
4561 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004562 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 != PackageManager.PERMISSION_GRANTED) {
4564 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566
Jim Miller284b62e2010-06-08 14:27:42 -07004567 synchronized (mKeyguardTokenWatcher) {
4568 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004569
Jim Miller284b62e2010-06-08 14:27:42 -07004570 if (!mKeyguardTokenWatcher.isAcquired()) {
4571 // If we are the last one to reenable the keyguard wait until
4572 // we have actually finished reenabling until returning.
4573 // It is possible that reenableKeyguard() can be called before
4574 // the previous disableKeyguard() is handled, in which case
4575 // neither mKeyguardTokenWatcher.acquired() or released() would
4576 // be called. In that case mKeyguardDisabled will be false here
4577 // and we have nothing to wait for.
4578 while (mKeyguardDisabled) {
4579 try {
4580 mKeyguardTokenWatcher.wait();
4581 } catch (InterruptedException e) {
4582 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 }
4584 }
4585 }
4586 }
4587 }
4588
4589 /**
4590 * @see android.app.KeyguardManager#exitKeyguardSecurely
4591 */
4592 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004593 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004594 != PackageManager.PERMISSION_GRANTED) {
4595 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4596 }
4597 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4598 public void onKeyguardExitResult(boolean success) {
4599 try {
4600 callback.onKeyguardExitResult(success);
4601 } catch (RemoteException e) {
4602 // Client has died, we don't care.
4603 }
4604 }
4605 });
4606 }
4607
4608 public boolean inKeyguardRestrictedInputMode() {
4609 return mPolicy.inKeyguardRestrictedKeyInputMode();
4610 }
Romain Guy06882f82009-06-10 13:36:04 -07004611
Dianne Hackbornffa42482009-09-23 22:20:11 -07004612 public void closeSystemDialogs(String reason) {
4613 synchronized(mWindowMap) {
4614 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004615 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004616 if (w.mSurface != null) {
4617 try {
4618 w.mClient.closeSystemDialogs(reason);
4619 } catch (RemoteException e) {
4620 }
4621 }
4622 }
4623 }
4624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 static float fixScale(float scale) {
4627 if (scale < 0) scale = 0;
4628 else if (scale > 20) scale = 20;
4629 return Math.abs(scale);
4630 }
Romain Guy06882f82009-06-10 13:36:04 -07004631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632 public void setAnimationScale(int which, float scale) {
4633 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4634 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004635 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 }
4637
4638 if (scale < 0) scale = 0;
4639 else if (scale > 20) scale = 20;
4640 scale = Math.abs(scale);
4641 switch (which) {
4642 case 0: mWindowAnimationScale = fixScale(scale); break;
4643 case 1: mTransitionAnimationScale = fixScale(scale); break;
4644 }
Romain Guy06882f82009-06-10 13:36:04 -07004645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 // Persist setting
4647 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4648 }
Romain Guy06882f82009-06-10 13:36:04 -07004649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 public void setAnimationScales(float[] scales) {
4651 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4652 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004653 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 }
4655
4656 if (scales != null) {
4657 if (scales.length >= 1) {
4658 mWindowAnimationScale = fixScale(scales[0]);
4659 }
4660 if (scales.length >= 2) {
4661 mTransitionAnimationScale = fixScale(scales[1]);
4662 }
4663 }
Romain Guy06882f82009-06-10 13:36:04 -07004664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004665 // Persist setting
4666 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4667 }
Romain Guy06882f82009-06-10 13:36:04 -07004668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 public float getAnimationScale(int which) {
4670 switch (which) {
4671 case 0: return mWindowAnimationScale;
4672 case 1: return mTransitionAnimationScale;
4673 }
4674 return 0;
4675 }
Romain Guy06882f82009-06-10 13:36:04 -07004676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 public float[] getAnimationScales() {
4678 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4679 }
Romain Guy06882f82009-06-10 13:36:04 -07004680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 public int getSwitchState(int sw) {
4682 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4683 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004684 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004686 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 }
Romain Guy06882f82009-06-10 13:36:04 -07004688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 public int getSwitchStateForDevice(int devid, int sw) {
4690 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4691 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004692 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004694 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 }
Romain Guy06882f82009-06-10 13:36:04 -07004696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 public int getScancodeState(int sw) {
4698 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4699 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004700 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004702 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703 }
Romain Guy06882f82009-06-10 13:36:04 -07004704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 public int getScancodeStateForDevice(int devid, int sw) {
4706 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4707 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004708 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004710 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 }
Romain Guy06882f82009-06-10 13:36:04 -07004712
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004713 public int getTrackballScancodeState(int sw) {
4714 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4715 "getTrackballScancodeState()")) {
4716 throw new SecurityException("Requires READ_INPUT_STATE permission");
4717 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004718 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004719 }
4720
4721 public int getDPadScancodeState(int sw) {
4722 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4723 "getDPadScancodeState()")) {
4724 throw new SecurityException("Requires READ_INPUT_STATE permission");
4725 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004726 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004727 }
4728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 public int getKeycodeState(int sw) {
4730 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4731 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004732 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004734 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 }
Romain Guy06882f82009-06-10 13:36:04 -07004736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 public int getKeycodeStateForDevice(int devid, int sw) {
4738 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4739 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004740 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004742 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 }
Romain Guy06882f82009-06-10 13:36:04 -07004744
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004745 public int getTrackballKeycodeState(int sw) {
4746 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4747 "getTrackballKeycodeState()")) {
4748 throw new SecurityException("Requires READ_INPUT_STATE permission");
4749 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004750 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004751 }
4752
4753 public int getDPadKeycodeState(int sw) {
4754 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4755 "getDPadKeycodeState()")) {
4756 throw new SecurityException("Requires READ_INPUT_STATE permission");
4757 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004758 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004759 }
Jeff Browna41ca772010-08-11 14:46:32 -07004760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004762 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 }
Romain Guy06882f82009-06-10 13:36:04 -07004764
Jeff Browna41ca772010-08-11 14:46:32 -07004765 public InputChannel monitorInput(String inputChannelName) {
4766 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4767 "monitorInput()")) {
4768 throw new SecurityException("Requires READ_INPUT_STATE permission");
4769 }
4770 return mInputManager.monitorInput(inputChannelName);
4771 }
4772
Jeff Brown8d608662010-08-30 03:02:23 -07004773 public InputDevice getInputDevice(int deviceId) {
4774 return mInputManager.getInputDevice(deviceId);
4775 }
4776
4777 public int[] getInputDeviceIds() {
4778 return mInputManager.getInputDeviceIds();
4779 }
4780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 public void enableScreenAfterBoot() {
4782 synchronized(mWindowMap) {
4783 if (mSystemBooted) {
4784 return;
4785 }
4786 mSystemBooted = true;
4787 }
Romain Guy06882f82009-06-10 13:36:04 -07004788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 performEnableScreen();
4790 }
Romain Guy06882f82009-06-10 13:36:04 -07004791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 public void enableScreenIfNeededLocked() {
4793 if (mDisplayEnabled) {
4794 return;
4795 }
4796 if (!mSystemBooted) {
4797 return;
4798 }
4799 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4800 }
Romain Guy06882f82009-06-10 13:36:04 -07004801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 public void performEnableScreen() {
4803 synchronized(mWindowMap) {
4804 if (mDisplayEnabled) {
4805 return;
4806 }
4807 if (!mSystemBooted) {
4808 return;
4809 }
Romain Guy06882f82009-06-10 13:36:04 -07004810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004811 // Don't enable the screen until all existing windows
4812 // have been drawn.
4813 final int N = mWindows.size();
4814 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004815 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004816 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004817 return;
4818 }
4819 }
Romain Guy06882f82009-06-10 13:36:04 -07004820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 mDisplayEnabled = true;
4822 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004823 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 StringWriter sw = new StringWriter();
4825 PrintWriter pw = new PrintWriter(sw);
4826 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004827 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004828 }
4829 try {
4830 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4831 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004832 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004833 Parcel data = Parcel.obtain();
4834 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4835 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4836 data, null, 0);
4837 data.recycle();
4838 }
4839 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004840 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004841 }
4842 }
Romain Guy06882f82009-06-10 13:36:04 -07004843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004847 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4848 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 }
Romain Guy06882f82009-06-10 13:36:04 -07004850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 public void setInTouchMode(boolean mode) {
4852 synchronized(mWindowMap) {
4853 mInTouchMode = mode;
4854 }
4855 }
4856
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004857 public void freezeRotation() {
4858 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4859 "setRotation()")) {
4860 throw new SecurityException("Requires SET_ORIENTATION permission");
4861 }
4862
4863 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
4864 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4865 }
4866
4867 public void thawRotation() {
4868 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4869 "setRotation()")) {
4870 throw new SecurityException("Requires SET_ORIENTATION permission");
4871 }
4872
4873 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
4874 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4875 }
4876
Romain Guy06882f82009-06-10 13:36:04 -07004877 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004878 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004880 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004881 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 }
4883
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004884 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004885 }
Romain Guy06882f82009-06-10 13:36:04 -07004886
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004887 public void setRotationUnchecked(int rotation,
4888 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004889 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 long origId = Binder.clearCallingIdentity();
4893 boolean changed;
4894 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004895 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004896 }
Romain Guy06882f82009-06-10 13:36:04 -07004897
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004898 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004899 sendNewConfiguration();
4900 }
Romain Guy06882f82009-06-10 13:36:04 -07004901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902 Binder.restoreCallingIdentity(origId);
4903 }
Romain Guy06882f82009-06-10 13:36:04 -07004904
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004905 /**
4906 * Apply a new rotation to the screen, respecting the requests of
4907 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4908 * re-evaluate the desired rotation.
4909 *
4910 * Returns null if the rotation has been changed. In this case YOU
4911 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4912 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004913 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 boolean changed;
4915 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4916 rotation = mRequestedRotation;
4917 } else {
4918 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004919 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004920 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004921 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004922 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004924 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004928 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 "Rotation changed to " + rotation
4930 + " from " + mRotation
4931 + " (forceApp=" + mForcedAppOrientation
4932 + ", req=" + mRequestedRotation + ")");
4933 mRotation = rotation;
4934 mWindowsFreezingScreen = true;
4935 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4936 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4937 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004938 mWaitingForConfig = true;
4939 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004941 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004942 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004944 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 }
4946 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004947 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948 if (w.mSurface != null) {
4949 w.mOrientationChanging = true;
4950 }
4951 }
4952 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4953 try {
4954 mRotationWatchers.get(i).onRotationChanged(rotation);
4955 } catch (RemoteException e) {
4956 }
4957 }
4958 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004960 return changed;
4961 }
Romain Guy06882f82009-06-10 13:36:04 -07004962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 public int getRotation() {
4964 return mRotation;
4965 }
4966
4967 public int watchRotation(IRotationWatcher watcher) {
4968 final IBinder watcherBinder = watcher.asBinder();
4969 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4970 public void binderDied() {
4971 synchronized (mWindowMap) {
4972 for (int i=0; i<mRotationWatchers.size(); i++) {
4973 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004974 IRotationWatcher removed = mRotationWatchers.remove(i);
4975 if (removed != null) {
4976 removed.asBinder().unlinkToDeath(this, 0);
4977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978 i--;
4979 }
4980 }
4981 }
4982 }
4983 };
Romain Guy06882f82009-06-10 13:36:04 -07004984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 synchronized (mWindowMap) {
4986 try {
4987 watcher.asBinder().linkToDeath(dr, 0);
4988 mRotationWatchers.add(watcher);
4989 } catch (RemoteException e) {
4990 // Client died, no cleanup needed.
4991 }
Romain Guy06882f82009-06-10 13:36:04 -07004992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993 return mRotation;
4994 }
4995 }
4996
4997 /**
4998 * Starts the view server on the specified port.
4999 *
5000 * @param port The port to listener to.
5001 *
5002 * @return True if the server was successfully started, false otherwise.
5003 *
5004 * @see com.android.server.ViewServer
5005 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5006 */
5007 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005008 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 return false;
5010 }
5011
5012 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5013 return false;
5014 }
5015
5016 if (port < 1024) {
5017 return false;
5018 }
5019
5020 if (mViewServer != null) {
5021 if (!mViewServer.isRunning()) {
5022 try {
5023 return mViewServer.start();
5024 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005025 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 }
5027 }
5028 return false;
5029 }
5030
5031 try {
5032 mViewServer = new ViewServer(this, port);
5033 return mViewServer.start();
5034 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005035 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005036 }
5037 return false;
5038 }
5039
Romain Guy06882f82009-06-10 13:36:04 -07005040 private boolean isSystemSecure() {
5041 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5042 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5043 }
5044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 /**
5046 * Stops the view server if it exists.
5047 *
5048 * @return True if the server stopped, false if it wasn't started or
5049 * couldn't be stopped.
5050 *
5051 * @see com.android.server.ViewServer
5052 */
5053 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005054 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 return false;
5056 }
5057
5058 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5059 return false;
5060 }
5061
5062 if (mViewServer != null) {
5063 return mViewServer.stop();
5064 }
5065 return false;
5066 }
5067
5068 /**
5069 * Indicates whether the view server is running.
5070 *
5071 * @return True if the server is running, false otherwise.
5072 *
5073 * @see com.android.server.ViewServer
5074 */
5075 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005076 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005077 return false;
5078 }
5079
5080 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5081 return false;
5082 }
5083
5084 return mViewServer != null && mViewServer.isRunning();
5085 }
5086
5087 /**
5088 * Lists all availble windows in the system. The listing is written in the
5089 * specified Socket's output stream with the following syntax:
5090 * windowHashCodeInHexadecimal windowName
5091 * Each line of the ouput represents a different window.
5092 *
5093 * @param client The remote client to send the listing to.
5094 * @return False if an error occured, true otherwise.
5095 */
5096 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005097 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005098 return false;
5099 }
5100
5101 boolean result = true;
5102
Jeff Browne33348b2010-07-15 23:54:05 -07005103 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005104 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005106 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005107 }
5108
5109 BufferedWriter out = null;
5110
5111 // Any uncaught exception will crash the system process
5112 try {
5113 OutputStream clientStream = client.getOutputStream();
5114 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5115
5116 final int count = windows.length;
5117 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005118 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 out.write(Integer.toHexString(System.identityHashCode(w)));
5120 out.write(' ');
5121 out.append(w.mAttrs.getTitle());
5122 out.write('\n');
5123 }
5124
5125 out.write("DONE.\n");
5126 out.flush();
5127 } catch (Exception e) {
5128 result = false;
5129 } finally {
5130 if (out != null) {
5131 try {
5132 out.close();
5133 } catch (IOException e) {
5134 result = false;
5135 }
5136 }
5137 }
5138
5139 return result;
5140 }
5141
5142 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005143 * Returns the focused window in the following format:
5144 * windowHashCodeInHexadecimal windowName
5145 *
5146 * @param client The remote client to send the listing to.
5147 * @return False if an error occurred, true otherwise.
5148 */
5149 boolean viewServerGetFocusedWindow(Socket client) {
5150 if (isSystemSecure()) {
5151 return false;
5152 }
5153
5154 boolean result = true;
5155
5156 WindowState focusedWindow = getFocusedWindow();
5157
5158 BufferedWriter out = null;
5159
5160 // Any uncaught exception will crash the system process
5161 try {
5162 OutputStream clientStream = client.getOutputStream();
5163 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5164
5165 if(focusedWindow != null) {
5166 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5167 out.write(' ');
5168 out.append(focusedWindow.mAttrs.getTitle());
5169 }
5170 out.write('\n');
5171 out.flush();
5172 } catch (Exception e) {
5173 result = false;
5174 } finally {
5175 if (out != null) {
5176 try {
5177 out.close();
5178 } catch (IOException e) {
5179 result = false;
5180 }
5181 }
5182 }
5183
5184 return result;
5185 }
5186
5187 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 * Sends a command to a target window. The result of the command, if any, will be
5189 * written in the output stream of the specified socket.
5190 *
5191 * The parameters must follow this syntax:
5192 * windowHashcode extra
5193 *
5194 * Where XX is the length in characeters of the windowTitle.
5195 *
5196 * The first parameter is the target window. The window with the specified hashcode
5197 * will be the target. If no target can be found, nothing happens. The extra parameters
5198 * will be delivered to the target window and as parameters to the command itself.
5199 *
5200 * @param client The remote client to sent the result, if any, to.
5201 * @param command The command to execute.
5202 * @param parameters The command parameters.
5203 *
5204 * @return True if the command was successfully delivered, false otherwise. This does
5205 * not indicate whether the command itself was successful.
5206 */
5207 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005208 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005209 return false;
5210 }
5211
5212 boolean success = true;
5213 Parcel data = null;
5214 Parcel reply = null;
5215
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005216 BufferedWriter out = null;
5217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 // Any uncaught exception will crash the system process
5219 try {
5220 // Find the hashcode of the window
5221 int index = parameters.indexOf(' ');
5222 if (index == -1) {
5223 index = parameters.length();
5224 }
5225 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005226 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227
5228 // Extract the command's parameter after the window description
5229 if (index < parameters.length()) {
5230 parameters = parameters.substring(index + 1);
5231 } else {
5232 parameters = "";
5233 }
5234
5235 final WindowManagerService.WindowState window = findWindow(hashCode);
5236 if (window == null) {
5237 return false;
5238 }
5239
5240 data = Parcel.obtain();
5241 data.writeInterfaceToken("android.view.IWindow");
5242 data.writeString(command);
5243 data.writeString(parameters);
5244 data.writeInt(1);
5245 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5246
5247 reply = Parcel.obtain();
5248
5249 final IBinder binder = window.mClient.asBinder();
5250 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5251 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5252
5253 reply.readException();
5254
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005255 if (!client.isOutputShutdown()) {
5256 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5257 out.write("DONE\n");
5258 out.flush();
5259 }
5260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005262 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 success = false;
5264 } finally {
5265 if (data != null) {
5266 data.recycle();
5267 }
5268 if (reply != null) {
5269 reply.recycle();
5270 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005271 if (out != null) {
5272 try {
5273 out.close();
5274 } catch (IOException e) {
5275
5276 }
5277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005278 }
5279
5280 return success;
5281 }
5282
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005283 public void addWindowChangeListener(WindowChangeListener listener) {
5284 synchronized(mWindowMap) {
5285 mWindowChangeListeners.add(listener);
5286 }
5287 }
5288
5289 public void removeWindowChangeListener(WindowChangeListener listener) {
5290 synchronized(mWindowMap) {
5291 mWindowChangeListeners.remove(listener);
5292 }
5293 }
5294
5295 private void notifyWindowsChanged() {
5296 WindowChangeListener[] windowChangeListeners;
5297 synchronized(mWindowMap) {
5298 if(mWindowChangeListeners.isEmpty()) {
5299 return;
5300 }
5301 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5302 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5303 }
5304 int N = windowChangeListeners.length;
5305 for(int i = 0; i < N; i++) {
5306 windowChangeListeners[i].windowsChanged();
5307 }
5308 }
5309
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005310 private void notifyFocusChanged() {
5311 WindowChangeListener[] windowChangeListeners;
5312 synchronized(mWindowMap) {
5313 if(mWindowChangeListeners.isEmpty()) {
5314 return;
5315 }
5316 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5317 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5318 }
5319 int N = windowChangeListeners.length;
5320 for(int i = 0; i < N; i++) {
5321 windowChangeListeners[i].focusChanged();
5322 }
5323 }
5324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 private WindowState findWindow(int hashCode) {
5326 if (hashCode == -1) {
5327 return getFocusedWindow();
5328 }
5329
5330 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005331 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 final int count = windows.size();
5333
5334 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005335 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005336 if (System.identityHashCode(w) == hashCode) {
5337 return w;
5338 }
5339 }
5340 }
5341
5342 return null;
5343 }
5344
5345 /*
5346 * Instruct the Activity Manager to fetch the current configuration and broadcast
5347 * that to config-changed listeners if appropriate.
5348 */
5349 void sendNewConfiguration() {
5350 try {
5351 mActivityManager.updateConfiguration(null);
5352 } catch (RemoteException e) {
5353 }
5354 }
Romain Guy06882f82009-06-10 13:36:04 -07005355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005356 public Configuration computeNewConfiguration() {
5357 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005358 return computeNewConfigurationLocked();
5359 }
5360 }
Romain Guy06882f82009-06-10 13:36:04 -07005361
Dianne Hackbornc485a602009-03-24 22:39:49 -07005362 Configuration computeNewConfigurationLocked() {
5363 Configuration config = new Configuration();
5364 if (!computeNewConfigurationLocked(config)) {
5365 return null;
5366 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005367 return config;
5368 }
Romain Guy06882f82009-06-10 13:36:04 -07005369
Dianne Hackbornc485a602009-03-24 22:39:49 -07005370 boolean computeNewConfigurationLocked(Configuration config) {
5371 if (mDisplay == null) {
5372 return false;
5373 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005374
5375 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005376
5377 // Use the effective "visual" dimensions based on current rotation
5378 final boolean rotated = (mRotation == Surface.ROTATION_90
5379 || mRotation == Surface.ROTATION_270);
5380 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5381 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5382
Dianne Hackbornc485a602009-03-24 22:39:49 -07005383 int orientation = Configuration.ORIENTATION_SQUARE;
5384 if (dw < dh) {
5385 orientation = Configuration.ORIENTATION_PORTRAIT;
5386 } else if (dw > dh) {
5387 orientation = Configuration.ORIENTATION_LANDSCAPE;
5388 }
5389 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005390
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005391 DisplayMetrics dm = new DisplayMetrics();
5392 mDisplay.getMetrics(dm);
5393 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5394
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005395 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005396 // Note we only do this once because at this point we don't
5397 // expect the screen to change in this way at runtime, and want
5398 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005399 int longSize = dw;
5400 int shortSize = dh;
5401 if (longSize < shortSize) {
5402 int tmp = longSize;
5403 longSize = shortSize;
5404 shortSize = tmp;
5405 }
5406 longSize = (int)(longSize/dm.density);
5407 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005408
Dianne Hackborn723738c2009-06-25 19:48:04 -07005409 // These semi-magic numbers define our compatibility modes for
5410 // applications with different screens. Don't change unless you
5411 // make sure to test lots and lots of apps!
5412 if (longSize < 470) {
5413 // This is shorter than an HVGA normal density screen (which
5414 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005415 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5416 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005417 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005418 // What size is this screen screen?
5419 if (longSize >= 800 && shortSize >= 600) {
5420 // SVGA or larger screens at medium density are the point
5421 // at which we consider it to be an extra large screen.
5422 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005423 } else if (longSize >= 530 && shortSize >= 400) {
5424 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005425 // at which we consider it to be a large screen.
5426 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5427 } else {
5428 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005429
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005430 // If this screen is wider than normal HVGA, or taller
5431 // than FWVGA, then for old apps we want to run in size
5432 // compatibility mode.
5433 if (shortSize > 321 || longSize > 570) {
5434 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5435 }
5436 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005437
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005438 // Is this a long screen?
5439 if (((longSize*3)/5) >= (shortSize-1)) {
5440 // Anything wider than WVGA (5:3) is considering to be long.
5441 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5442 } else {
5443 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5444 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005445 }
5446 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005447 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005448
Dianne Hackbornc485a602009-03-24 22:39:49 -07005449 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5450 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5451 mPolicy.adjustConfigurationLw(config);
5452 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005454
5455 // -------------------------------------------------------------
5456 // Drag and drop
5457 // -------------------------------------------------------------
5458
5459 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
5460 boolean localOnly, int width, int height, Surface outSurface) {
5461 if (DEBUG_DRAG) {
5462 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
5463 + " local=" + localOnly + " win=" + window
5464 + " asbinder=" + window.asBinder());
5465 }
5466
5467 final int callerPid = Binder.getCallingPid();
5468 final long origId = Binder.clearCallingIdentity();
5469 IBinder token = null;
5470
5471 try {
5472 synchronized (mWindowMap) {
5473 try {
5474 // !!! TODO: fail if the given window does not currently have touch focus?
5475
5476 if (mDragState == null) {
5477 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5478 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5479 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005480 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005481 token = new Binder();
Chris Tate7b362e42010-11-04 16:02:52 -07005482 mDragState = new DragState(token, surface, localOnly, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005483 mDragState.mSurface = surface;
5484 mDragState.mLocalOnly = localOnly;
5485 token = mDragState.mToken = new Binder();
5486
5487 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005488 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5489 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005490 mH.sendMessageDelayed(msg, 5000);
5491 } else {
5492 Slog.w(TAG, "Drag already in progress");
5493 }
5494 } catch (Surface.OutOfResourcesException e) {
5495 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5496 if (mDragState != null) {
5497 mDragState.reset();
5498 mDragState = null;
5499 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005500 }
5501 }
5502 } finally {
5503 Binder.restoreCallingIdentity(origId);
5504 }
5505
5506 return token;
5507 }
5508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005509 // -------------------------------------------------------------
5510 // Input Events and Focus Management
5511 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005512
Jeff Brown349703e2010-06-22 01:27:15 -07005513 InputMonitor mInputMonitor = new InputMonitor();
5514
5515 /* Tracks the progress of input dispatch and ensures that input dispatch state
5516 * is kept in sync with changes in window focus, visibility, registration, and
5517 * other relevant Window Manager state transitions. */
5518 final class InputMonitor {
5519 // Current window with input focus for keys and other non-touch events. May be null.
5520 private WindowState mInputFocus;
5521
5522 // When true, prevents input dispatch from proceeding until set to false again.
5523 private boolean mInputDispatchFrozen;
5524
5525 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5526 private boolean mInputDispatchEnabled = true;
5527
5528 // Temporary list of windows information to provide to the input dispatcher.
5529 private InputWindowList mTempInputWindows = new InputWindowList();
5530
5531 // Temporary input application object to provide to the input dispatcher.
5532 private InputApplication mTempInputApplication = new InputApplication();
5533
5534 /* Notifies the window manager about a broken input channel.
5535 *
5536 * Called by the InputManager.
5537 */
5538 public void notifyInputChannelBroken(InputChannel inputChannel) {
5539 synchronized (mWindowMap) {
5540 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5541 if (windowState == null) {
5542 return; // irrelevant
5543 }
5544
5545 Slog.i(TAG, "WINDOW DIED " + windowState);
5546 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005547 }
5548 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005549
Jeff Brown519e0242010-09-15 15:18:56 -07005550 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005551 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005552 *
5553 * Called by the InputManager.
5554 */
Jeff Brown519e0242010-09-15 15:18:56 -07005555 public long notifyANR(Object token, InputChannel inputChannel) {
5556 AppWindowToken appWindowToken = null;
5557 if (inputChannel != null) {
5558 synchronized (mWindowMap) {
5559 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5560 if (windowState != null) {
5561 Slog.i(TAG, "Input event dispatching timed out sending to "
5562 + windowState.mAttrs.getTitle());
5563 appWindowToken = windowState.mAppToken;
5564 }
Jeff Brown349703e2010-06-22 01:27:15 -07005565 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005566 }
5567
Jeff Brown519e0242010-09-15 15:18:56 -07005568 if (appWindowToken == null && token != null) {
5569 appWindowToken = (AppWindowToken) token;
5570 Slog.i(TAG, "Input event dispatching timed out sending to application "
5571 + appWindowToken.stringName);
5572 }
Jeff Brown349703e2010-06-22 01:27:15 -07005573
Jeff Brown519e0242010-09-15 15:18:56 -07005574 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005575 try {
5576 // Notify the activity manager about the timeout and let it decide whether
5577 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005578 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005579 if (! abort) {
5580 // The activity manager declined to abort dispatching.
5581 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005582 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005583 }
Jeff Brown349703e2010-06-22 01:27:15 -07005584 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005585 }
5586 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005587 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005588 }
5589
Jeff Brown349703e2010-06-22 01:27:15 -07005590 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5591 synchronized (mWindowMap) {
5592 return getWindowStateForInputChannelLocked(inputChannel);
5593 }
5594 }
5595
5596 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5597 int windowCount = mWindows.size();
5598 for (int i = 0; i < windowCount; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005599 WindowState windowState = mWindows.get(i);
Jeff Brown349703e2010-06-22 01:27:15 -07005600 if (windowState.mInputChannel == inputChannel) {
5601 return windowState;
5602 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005603 }
5604
Jeff Brown349703e2010-06-22 01:27:15 -07005605 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005606 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005607
Chris Tatea32dcf72010-10-14 12:13:50 -07005608 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005609 final InputWindow inputWindow = windowList.add();
5610 inputWindow.inputChannel = mDragState.mServerChannel;
5611 inputWindow.name = "drag";
5612 inputWindow.layoutParamsFlags = 0;
5613 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5614 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5615 inputWindow.visible = true;
5616 inputWindow.canReceiveKeys = false;
5617 inputWindow.hasFocus = true;
5618 inputWindow.hasWallpaper = false;
5619 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07005620 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07005621 inputWindow.ownerPid = Process.myPid();
5622 inputWindow.ownerUid = Process.myUid();
5623
5624 // The drag window covers the entire display
5625 inputWindow.frameLeft = 0;
5626 inputWindow.frameTop = 0;
5627 inputWindow.frameRight = mDisplay.getWidth();
5628 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005629
Christopher Tatea53146c2010-09-07 11:57:52 -07005630 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5631 inputWindow.visibleFrameTop = inputWindow.frameTop;
5632 inputWindow.visibleFrameRight = inputWindow.frameRight;
5633 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5634
5635 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5636 inputWindow.touchableAreaTop = inputWindow.frameTop;
5637 inputWindow.touchableAreaRight = inputWindow.frameRight;
5638 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5639 }
5640
Jeff Brown349703e2010-06-22 01:27:15 -07005641 /* Updates the cached window information provided to the input dispatcher. */
5642 public void updateInputWindowsLw() {
5643 // Populate the input window list with information about all of the windows that
5644 // could potentially receive input.
5645 // As an optimization, we could try to prune the list of windows but this turns
5646 // out to be difficult because only the native code knows for sure which window
5647 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005648 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005649
5650 // If there's a drag in flight, provide a pseudowindow to catch drag input
5651 final boolean inDrag = (mDragState != null);
5652 if (inDrag) {
5653 if (DEBUG_DRAG) {
5654 Log.d(TAG, "Inserting drag window");
5655 }
Chris Tatea32dcf72010-10-14 12:13:50 -07005656 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07005657 }
5658
Jeff Brown7fbdc842010-06-17 20:52:56 -07005659 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005660 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005661 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005662 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005663 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005664 continue;
5665 }
5666
Jeff Brown349703e2010-06-22 01:27:15 -07005667 final int flags = child.mAttrs.flags;
5668 final int type = child.mAttrs.type;
5669
5670 final boolean hasFocus = (child == mInputFocus);
5671 final boolean isVisible = child.isVisibleLw();
5672 final boolean hasWallpaper = (child == mWallpaperTarget)
5673 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005674
5675 // If there's a drag in progress and 'child' is a potential drop target,
5676 // make sure it's been told about the drag
5677 if (inDrag && isVisible) {
5678 mDragState.sendDragStartedIfNeededLw(child);
5679 }
5680
Jeff Brown349703e2010-06-22 01:27:15 -07005681 // Add a window to our list of input windows.
5682 final InputWindow inputWindow = mTempInputWindows.add();
5683 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005684 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005685 inputWindow.layoutParamsFlags = flags;
5686 inputWindow.layoutParamsType = type;
5687 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5688 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005689 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005690 inputWindow.hasFocus = hasFocus;
5691 inputWindow.hasWallpaper = hasWallpaper;
5692 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005693 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005694 inputWindow.ownerPid = child.mSession.mPid;
5695 inputWindow.ownerUid = child.mSession.mUid;
5696
5697 final Rect frame = child.mFrame;
5698 inputWindow.frameLeft = frame.left;
5699 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005700 inputWindow.frameRight = frame.right;
5701 inputWindow.frameBottom = frame.bottom;
5702
5703 final Rect visibleFrame = child.mVisibleFrame;
5704 inputWindow.visibleFrameLeft = visibleFrame.left;
5705 inputWindow.visibleFrameTop = visibleFrame.top;
5706 inputWindow.visibleFrameRight = visibleFrame.right;
5707 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005708
5709 switch (child.mTouchableInsets) {
5710 default:
5711 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5712 inputWindow.touchableAreaLeft = frame.left;
5713 inputWindow.touchableAreaTop = frame.top;
5714 inputWindow.touchableAreaRight = frame.right;
5715 inputWindow.touchableAreaBottom = frame.bottom;
5716 break;
5717
5718 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5719 Rect inset = child.mGivenContentInsets;
5720 inputWindow.touchableAreaLeft = frame.left + inset.left;
5721 inputWindow.touchableAreaTop = frame.top + inset.top;
5722 inputWindow.touchableAreaRight = frame.right - inset.right;
5723 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5724 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005725 }
Jeff Brown349703e2010-06-22 01:27:15 -07005726
5727 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5728 Rect inset = child.mGivenVisibleInsets;
5729 inputWindow.touchableAreaLeft = frame.left + inset.left;
5730 inputWindow.touchableAreaTop = frame.top + inset.top;
5731 inputWindow.touchableAreaRight = frame.right - inset.right;
5732 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005733 break;
5734 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005735 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005736 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005737
Jeff Brown349703e2010-06-22 01:27:15 -07005738 // Send windows to native code.
5739 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005740
Jeff Brown349703e2010-06-22 01:27:15 -07005741 // Clear the list in preparation for the next round.
5742 // Also avoids keeping InputChannel objects referenced unnecessarily.
5743 mTempInputWindows.clear();
5744 }
5745
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005746 /* Notifies that the lid switch changed state. */
5747 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5748 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5749 }
5750
Jeff Brown349703e2010-06-22 01:27:15 -07005751 /* Provides an opportunity for the window manager policy to intercept early key
5752 * processing as soon as the key has been read from the device. */
Jeff Brown4d396052010-10-29 21:50:21 -07005753 public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
5754 int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
5755 return mPolicy.interceptKeyBeforeQueueing(whenNanos, action, flags,
5756 keyCode, scanCode, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005757 }
5758
5759 /* Provides an opportunity for the window manager policy to process a key before
5760 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005761 public boolean interceptKeyBeforeDispatching(InputChannel focus,
Jeff Brown4d396052010-10-29 21:50:21 -07005762 int action, int flags, int keyCode, int scanCode, int metaState, int repeatCount,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005763 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005764 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005765 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
Jeff Brown4d396052010-10-29 21:50:21 -07005766 keyCode, scanCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005767 }
5768
5769 /* Called when the current input focus changes.
5770 * Layer assignment is assumed to be complete by the time this is called.
5771 */
5772 public void setInputFocusLw(WindowState newWindow) {
5773 if (DEBUG_INPUT) {
5774 Slog.d(TAG, "Input focus has changed to " + newWindow);
5775 }
5776
5777 if (newWindow != mInputFocus) {
5778 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005779 // Displaying a window implicitly causes dispatching to be unpaused.
5780 // This is to protect against bugs if someone pauses dispatching but
5781 // forgets to resume.
5782 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005783 }
Jeff Brown349703e2010-06-22 01:27:15 -07005784
5785 mInputFocus = newWindow;
5786 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005787 }
5788 }
5789
Jeff Brown349703e2010-06-22 01:27:15 -07005790 public void setFocusedAppLw(AppWindowToken newApp) {
5791 // Focused app has changed.
5792 if (newApp == null) {
5793 mInputManager.setFocusedApplication(null);
5794 } else {
5795 mTempInputApplication.name = newApp.toString();
5796 mTempInputApplication.dispatchingTimeoutNanos =
5797 newApp.inputDispatchingTimeoutNanos;
5798 mTempInputApplication.token = newApp;
5799
5800 mInputManager.setFocusedApplication(mTempInputApplication);
5801 }
5802 }
5803
Jeff Brown349703e2010-06-22 01:27:15 -07005804 public void pauseDispatchingLw(WindowToken window) {
5805 if (! window.paused) {
5806 if (DEBUG_INPUT) {
5807 Slog.v(TAG, "Pausing WindowToken " + window);
5808 }
5809
5810 window.paused = true;
5811 updateInputWindowsLw();
5812 }
5813 }
5814
5815 public void resumeDispatchingLw(WindowToken window) {
5816 if (window.paused) {
5817 if (DEBUG_INPUT) {
5818 Slog.v(TAG, "Resuming WindowToken " + window);
5819 }
5820
5821 window.paused = false;
5822 updateInputWindowsLw();
5823 }
5824 }
5825
5826 public void freezeInputDispatchingLw() {
5827 if (! mInputDispatchFrozen) {
5828 if (DEBUG_INPUT) {
5829 Slog.v(TAG, "Freezing input dispatching");
5830 }
5831
5832 mInputDispatchFrozen = true;
5833 updateInputDispatchModeLw();
5834 }
5835 }
5836
5837 public void thawInputDispatchingLw() {
5838 if (mInputDispatchFrozen) {
5839 if (DEBUG_INPUT) {
5840 Slog.v(TAG, "Thawing input dispatching");
5841 }
5842
5843 mInputDispatchFrozen = false;
5844 updateInputDispatchModeLw();
5845 }
5846 }
5847
5848 public void setEventDispatchingLw(boolean enabled) {
5849 if (mInputDispatchEnabled != enabled) {
5850 if (DEBUG_INPUT) {
5851 Slog.v(TAG, "Setting event dispatching to " + enabled);
5852 }
5853
5854 mInputDispatchEnabled = enabled;
5855 updateInputDispatchModeLw();
5856 }
5857 }
5858
5859 private void updateInputDispatchModeLw() {
5860 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5861 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005864 public void pauseKeyDispatching(IBinder _token) {
5865 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5866 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005867 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005868 }
5869
5870 synchronized (mWindowMap) {
5871 WindowToken token = mTokenMap.get(_token);
5872 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005873 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005874 }
5875 }
5876 }
5877
5878 public void resumeKeyDispatching(IBinder _token) {
5879 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5880 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005881 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 }
5883
5884 synchronized (mWindowMap) {
5885 WindowToken token = mTokenMap.get(_token);
5886 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005887 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 }
5889 }
5890 }
5891
5892 public void setEventDispatching(boolean enabled) {
5893 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5894 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005895 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005896 }
5897
5898 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005899 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 }
5901 }
Romain Guy06882f82009-06-10 13:36:04 -07005902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 /**
5904 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005905 * Even when sync is false, this method may block while waiting for current
5906 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005907 *
5908 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909 * {@link SystemClock#uptimeMillis()} as the timebase.)
5910 * @param sync If true, wait for the event to be completed before returning to the caller.
5911 * @return Returns true if event was dispatched, false if it was dropped for any reason
5912 */
5913 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5914 long downTime = ev.getDownTime();
5915 long eventTime = ev.getEventTime();
5916
5917 int action = ev.getAction();
5918 int code = ev.getKeyCode();
5919 int repeatCount = ev.getRepeatCount();
5920 int metaState = ev.getMetaState();
5921 int deviceId = ev.getDeviceId();
5922 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005923 int source = ev.getSource();
5924
5925 if (source == InputDevice.SOURCE_UNKNOWN) {
5926 source = InputDevice.SOURCE_KEYBOARD;
5927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005928
5929 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5930 if (downTime == 0) downTime = eventTime;
5931
5932 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jeff Brownc5ed5912010-07-14 18:48:53 -07005933 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005934
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005935 final int pid = Binder.getCallingPid();
5936 final int uid = Binder.getCallingUid();
5937 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005938
Jeff Brownbbda99d2010-07-28 15:48:59 -07005939 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5940 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5941 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5942 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005943
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005944 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005945 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 }
5947
5948 /**
5949 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005950 * Even when sync is false, this method may block while waiting for current
5951 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005952 *
5953 * @param ev A motion event describing the pointer (touch) action. (As noted in
5954 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 * {@link SystemClock#uptimeMillis()} as the timebase.)
5956 * @param sync If true, wait for the event to be completed before returning to the caller.
5957 * @return Returns true if event was dispatched, false if it was dropped for any reason
5958 */
5959 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005960 final int pid = Binder.getCallingPid();
5961 final int uid = Binder.getCallingUid();
5962 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005963
Jeff Brownc5ed5912010-07-14 18:48:53 -07005964 MotionEvent newEvent = MotionEvent.obtain(ev);
5965 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5966 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5967 }
5968
Jeff Brownbbda99d2010-07-28 15:48:59 -07005969 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5970 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5971 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5972 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005973
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005974 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005975 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005976 }
Romain Guy06882f82009-06-10 13:36:04 -07005977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 /**
5979 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005980 * Even when sync is false, this method may block while waiting for current
5981 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005982 *
5983 * @param ev A motion event describing the trackball action. (As noted in
5984 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 * {@link SystemClock#uptimeMillis()} as the timebase.)
5986 * @param sync If true, wait for the event to be completed before returning to the caller.
5987 * @return Returns true if event was dispatched, false if it was dropped for any reason
5988 */
5989 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005990 final int pid = Binder.getCallingPid();
5991 final int uid = Binder.getCallingUid();
5992 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005993
Jeff Brownc5ed5912010-07-14 18:48:53 -07005994 MotionEvent newEvent = MotionEvent.obtain(ev);
5995 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5996 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5997 }
5998
Jeff Brownbbda99d2010-07-28 15:48:59 -07005999 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6000 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6001 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6002 INJECTION_TIMEOUT_MILLIS);
6003
6004 Binder.restoreCallingIdentity(ident);
6005 return reportInjectionResult(result);
6006 }
6007
6008 /**
6009 * Inject an input event into the UI without waiting for dispatch to commence.
6010 * This variant is useful for fire-and-forget input event injection. It does not
6011 * block any longer than it takes to enqueue the input event.
6012 *
6013 * @param ev An input event. (Be sure to set the input source correctly.)
6014 * @return Returns true if event was dispatched, false if it was dropped for any reason
6015 */
6016 public boolean injectInputEventNoWait(InputEvent ev) {
6017 final int pid = Binder.getCallingPid();
6018 final int uid = Binder.getCallingUid();
6019 final long ident = Binder.clearCallingIdentity();
6020
6021 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6022 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6023 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006024
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006025 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006026 return reportInjectionResult(result);
6027 }
6028
6029 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006030 switch (result) {
6031 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6032 Slog.w(TAG, "Input event injection permission denied.");
6033 throw new SecurityException(
6034 "Injecting to another application requires INJECT_EVENTS permission");
6035 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006036 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006037 return true;
6038 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6039 Slog.w(TAG, "Input event injection timed out.");
6040 return false;
6041 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6042 default:
6043 Slog.w(TAG, "Input event injection failed.");
6044 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 }
Romain Guy06882f82009-06-10 13:36:04 -07006047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 private WindowState getFocusedWindow() {
6049 synchronized (mWindowMap) {
6050 return getFocusedWindowLocked();
6051 }
6052 }
6053
6054 private WindowState getFocusedWindowLocked() {
6055 return mCurrentFocus;
6056 }
Romain Guy06882f82009-06-10 13:36:04 -07006057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 public boolean detectSafeMode() {
6059 mSafeMode = mPolicy.detectSafeMode();
6060 return mSafeMode;
6061 }
Romain Guy06882f82009-06-10 13:36:04 -07006062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006063 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006064 synchronized(mWindowMap) {
6065 if (mDisplay != null) {
6066 throw new IllegalStateException("Display already initialized");
6067 }
6068 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6069 mDisplay = wm.getDefaultDisplay();
6070 mInitialDisplayWidth = mDisplay.getWidth();
6071 mInitialDisplayHeight = mDisplay.getHeight();
6072 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
6073 }
6074
6075 try {
6076 mActivityManager.updateConfiguration(null);
6077 } catch (RemoteException e) {
6078 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006079
6080 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006081 }
6082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 // -------------------------------------------------------------
6084 // Client Session State
6085 // -------------------------------------------------------------
6086
6087 private final class Session extends IWindowSession.Stub
6088 implements IBinder.DeathRecipient {
6089 final IInputMethodClient mClient;
6090 final IInputContext mInputContext;
6091 final int mUid;
6092 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006093 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 SurfaceSession mSurfaceSession;
6095 int mNumWindow = 0;
6096 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 public Session(IInputMethodClient client, IInputContext inputContext) {
6099 mClient = client;
6100 mInputContext = inputContext;
6101 mUid = Binder.getCallingUid();
6102 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006103 StringBuilder sb = new StringBuilder();
6104 sb.append("Session{");
6105 sb.append(Integer.toHexString(System.identityHashCode(this)));
6106 sb.append(" uid ");
6107 sb.append(mUid);
6108 sb.append("}");
6109 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 synchronized (mWindowMap) {
6112 if (mInputMethodManager == null && mHaveInputMethods) {
6113 IBinder b = ServiceManager.getService(
6114 Context.INPUT_METHOD_SERVICE);
6115 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6116 }
6117 }
6118 long ident = Binder.clearCallingIdentity();
6119 try {
6120 // Note: it is safe to call in to the input method manager
6121 // here because we are not holding our lock.
6122 if (mInputMethodManager != null) {
6123 mInputMethodManager.addClient(client, inputContext,
6124 mUid, mPid);
6125 } else {
6126 client.setUsingInputMethod(false);
6127 }
6128 client.asBinder().linkToDeath(this, 0);
6129 } catch (RemoteException e) {
6130 // The caller has died, so we can just forget about this.
6131 try {
6132 if (mInputMethodManager != null) {
6133 mInputMethodManager.removeClient(client);
6134 }
6135 } catch (RemoteException ee) {
6136 }
6137 } finally {
6138 Binder.restoreCallingIdentity(ident);
6139 }
6140 }
Romain Guy06882f82009-06-10 13:36:04 -07006141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 @Override
6143 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6144 throws RemoteException {
6145 try {
6146 return super.onTransact(code, data, reply, flags);
6147 } catch (RuntimeException e) {
6148 // Log all 'real' exceptions thrown to the caller
6149 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006150 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 }
6152 throw e;
6153 }
6154 }
6155
6156 public void binderDied() {
6157 // Note: it is safe to call in to the input method manager
6158 // here because we are not holding our lock.
6159 try {
6160 if (mInputMethodManager != null) {
6161 mInputMethodManager.removeClient(mClient);
6162 }
6163 } catch (RemoteException e) {
6164 }
6165 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006166 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 mClientDead = true;
6168 killSessionLocked();
6169 }
6170 }
6171
6172 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006173 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6174 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6175 outInputChannel);
6176 }
6177
6178 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006180 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006181 }
Romain Guy06882f82009-06-10 13:36:04 -07006182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 public void remove(IWindow window) {
6184 removeWindow(this, window);
6185 }
Romain Guy06882f82009-06-10 13:36:04 -07006186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006187 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6188 int requestedWidth, int requestedHeight, int viewFlags,
6189 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006190 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006191 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6192 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006193 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006194 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006195 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6196 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006197 }
Romain Guy06882f82009-06-10 13:36:04 -07006198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006199 public void setTransparentRegion(IWindow window, Region region) {
6200 setTransparentRegionWindow(this, window, region);
6201 }
Romain Guy06882f82009-06-10 13:36:04 -07006202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 public void setInsets(IWindow window, int touchableInsets,
6204 Rect contentInsets, Rect visibleInsets) {
6205 setInsetsWindow(this, window, touchableInsets, contentInsets,
6206 visibleInsets);
6207 }
Romain Guy06882f82009-06-10 13:36:04 -07006208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6210 getWindowDisplayFrame(this, window, outDisplayFrame);
6211 }
Romain Guy06882f82009-06-10 13:36:04 -07006212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006213 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006214 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006215 TAG, "IWindow finishDrawing called for " + window);
6216 finishDrawingWindow(this, window);
6217 }
6218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006219 public void setInTouchMode(boolean mode) {
6220 synchronized(mWindowMap) {
6221 mInTouchMode = mode;
6222 }
6223 }
6224
6225 public boolean getInTouchMode() {
6226 synchronized(mWindowMap) {
6227 return mInTouchMode;
6228 }
6229 }
6230
6231 public boolean performHapticFeedback(IWindow window, int effectId,
6232 boolean always) {
6233 synchronized(mWindowMap) {
6234 long ident = Binder.clearCallingIdentity();
6235 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006236 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006237 windowForClientLocked(this, window, true),
6238 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006239 } finally {
6240 Binder.restoreCallingIdentity(ident);
6241 }
6242 }
6243 }
Romain Guy06882f82009-06-10 13:36:04 -07006244
Christopher Tatea53146c2010-09-07 11:57:52 -07006245 /* Drag/drop */
6246 public IBinder prepareDrag(IWindow window, boolean localOnly,
6247 int width, int height, Surface outSurface) {
6248 return prepareDragSurface(window, mSurfaceSession, localOnly,
6249 width, height, outSurface);
6250 }
6251
6252 public boolean performDrag(IWindow window, IBinder dragToken,
6253 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6254 ClipData data) {
6255 if (DEBUG_DRAG) {
6256 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6257 }
6258
6259 synchronized (mWindowMap) {
6260 if (mDragState == null) {
6261 Slog.w(TAG, "No drag prepared");
6262 throw new IllegalStateException("performDrag() without prepareDrag()");
6263 }
6264
6265 if (dragToken != mDragState.mToken) {
6266 Slog.w(TAG, "Performing mismatched drag");
6267 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6268 }
6269
6270 WindowState callingWin = windowForClientLocked(null, window, false);
6271 if (callingWin == null) {
6272 Slog.w(TAG, "Bad requesting window " + window);
6273 return false; // !!! TODO: throw here?
6274 }
6275
6276 // !!! TODO: if input is not still focused on the initiating window, fail
6277 // the drag initiation (e.g. an alarm window popped up just as the application
6278 // called performDrag()
6279
6280 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6281
Christopher Tate2c095f32010-10-04 14:13:40 -07006282 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6283 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006284
Chris Tateb478f462010-10-15 16:02:26 -07006285 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6286 // the actual drag event dispatch stuff in the dragstate
6287
Christopher Tatea53146c2010-09-07 11:57:52 -07006288 mDragState.register();
6289 mInputMonitor.updateInputWindowsLw();
Chris Tateef70a072010-10-22 19:10:34 -07006290 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6291 mDragState.mServerChannel)) {
6292 Slog.e(TAG, "Unable to transfer touch focus");
6293 mDragState.unregister();
6294 mDragState = null;
6295 mInputMonitor.updateInputWindowsLw();
6296 return false;
6297 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006298
6299 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006300 mDragState.mCurrentX = touchX;
6301 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006302 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006303
6304 // remember the thumb offsets for later
6305 mDragState.mThumbOffsetX = thumbCenterX;
6306 mDragState.mThumbOffsetY = thumbCenterY;
6307
6308 // Make the surface visible at the proper location
6309 final Surface surface = mDragState.mSurface;
Chris Tateb478f462010-10-15 16:02:26 -07006310 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006311 try {
6312 surface.setPosition((int)(touchX - thumbCenterX),
6313 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006314 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006315 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006316 surface.show();
6317 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006318 Surface.closeTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006319 }
6320 }
6321
6322 return true; // success!
6323 }
6324
Chris Tated4533f142010-10-19 15:15:08 -07006325 public void reportDropResult(IWindow window, boolean consumed) {
6326 IBinder token = window.asBinder();
6327 if (DEBUG_DRAG) {
6328 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6329 }
6330
6331 synchronized (mWindowMap) {
6332 if (mDragState.mToken != token) {
6333 Slog.w(TAG, "Invalid drop-result claim by " + window);
6334 throw new IllegalStateException("reportDropResult() by non-recipient");
6335 }
6336
6337 // The right window has responded, even if it's no longer around,
6338 // so be sure to halt the timeout even if the later WindowState
6339 // lookup fails.
6340 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6341
6342 WindowState callingWin = windowForClientLocked(null, window, false);
6343 if (callingWin == null) {
6344 Slog.w(TAG, "Bad result-reporting window " + window);
6345 return; // !!! TODO: throw here?
6346 }
6347
6348 mDragState.mDragResult = consumed;
6349 mDragState.endDragLw();
6350 }
6351 }
6352
Christopher Tatea53146c2010-09-07 11:57:52 -07006353 public void dragRecipientEntered(IWindow window) {
6354 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006355 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006356 }
6357 }
6358
6359 public void dragRecipientExited(IWindow window) {
6360 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006361 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006362 }
6363 }
6364
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006365 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006366 synchronized(mWindowMap) {
6367 long ident = Binder.clearCallingIdentity();
6368 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006369 setWindowWallpaperPositionLocked(
6370 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006371 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006372 } finally {
6373 Binder.restoreCallingIdentity(ident);
6374 }
6375 }
6376 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006377
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006378 public void wallpaperOffsetsComplete(IBinder window) {
6379 WindowManagerService.this.wallpaperOffsetsComplete(window);
6380 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006381
Dianne Hackborn75804932009-10-20 20:15:20 -07006382 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6383 int z, Bundle extras, boolean sync) {
6384 synchronized(mWindowMap) {
6385 long ident = Binder.clearCallingIdentity();
6386 try {
6387 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006388 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006389 action, x, y, z, extras, sync);
6390 } finally {
6391 Binder.restoreCallingIdentity(ident);
6392 }
6393 }
6394 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006395
Dianne Hackborn75804932009-10-20 20:15:20 -07006396 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6397 WindowManagerService.this.wallpaperCommandComplete(window, result);
6398 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006400 void windowAddedLocked() {
6401 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006402 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 TAG, "First window added to " + this + ", creating SurfaceSession");
6404 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006405 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006406 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 mSessions.add(this);
6408 }
6409 mNumWindow++;
6410 }
6411
6412 void windowRemovedLocked() {
6413 mNumWindow--;
6414 killSessionLocked();
6415 }
Romain Guy06882f82009-06-10 13:36:04 -07006416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 void killSessionLocked() {
6418 if (mNumWindow <= 0 && mClientDead) {
6419 mSessions.remove(this);
6420 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006421 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006422 TAG, "Last window removed from " + this
6423 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006424 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006425 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006426 try {
6427 mSurfaceSession.kill();
6428 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006429 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 + mSurfaceSession + " in session " + this
6431 + ": " + e.toString());
6432 }
6433 mSurfaceSession = null;
6434 }
6435 }
6436 }
Romain Guy06882f82009-06-10 13:36:04 -07006437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006439 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6440 pw.print(" mClientDead="); pw.print(mClientDead);
6441 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006442 }
6443
6444 @Override
6445 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006446 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 }
6448 }
6449
6450 // -------------------------------------------------------------
6451 // Client Window State
6452 // -------------------------------------------------------------
6453
6454 private final class WindowState implements WindowManagerPolicy.WindowState {
6455 final Session mSession;
6456 final IWindow mClient;
6457 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006458 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 AppWindowToken mAppToken;
6460 AppWindowToken mTargetAppToken;
6461 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6462 final DeathRecipient mDeathRecipient;
6463 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006464 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 final int mBaseLayer;
6466 final int mSubLayer;
6467 final boolean mLayoutAttached;
6468 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006469 final boolean mIsWallpaper;
6470 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006471 int mViewVisibility;
6472 boolean mPolicyVisibility = true;
6473 boolean mPolicyVisibilityAfterAnim = true;
6474 boolean mAppFreezing;
6475 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006476 boolean mReportDestroySurface;
6477 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 boolean mAttachedHidden; // is our parent window hidden?
6479 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006480 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006481 int mRequestedWidth;
6482 int mRequestedHeight;
6483 int mLastRequestedWidth;
6484 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006485 int mLayer;
6486 int mAnimLayer;
6487 int mLastLayer;
6488 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006489 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006490 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006492 int mLayoutSeq = -1;
6493
6494 Configuration mConfiguration = null;
6495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006496 // Actual frame shown on-screen (may be modified by animation)
6497 final Rect mShownFrame = new Rect();
6498 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006501 * Set when we have changed the size of the surface, to know that
6502 * we must tell them application to resize (and thus redraw itself).
6503 */
6504 boolean mSurfaceResized;
6505
6506 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 * Insets that determine the actually visible area
6508 */
6509 final Rect mVisibleInsets = new Rect();
6510 final Rect mLastVisibleInsets = new Rect();
6511 boolean mVisibleInsetsChanged;
6512
6513 /**
6514 * Insets that are covered by system windows
6515 */
6516 final Rect mContentInsets = new Rect();
6517 final Rect mLastContentInsets = new Rect();
6518 boolean mContentInsetsChanged;
6519
6520 /**
6521 * Set to true if we are waiting for this window to receive its
6522 * given internal insets before laying out other windows based on it.
6523 */
6524 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006526 /**
6527 * These are the content insets that were given during layout for
6528 * this window, to be applied to windows behind it.
6529 */
6530 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 /**
6533 * These are the visible insets that were given during layout for
6534 * this window, to be applied to windows behind it.
6535 */
6536 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 /**
6539 * Flag indicating whether the touchable region should be adjusted by
6540 * the visible insets; if false the area outside the visible insets is
6541 * NOT touchable, so we must use those to adjust the frame during hit
6542 * tests.
6543 */
6544 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006546 // Current transformation being applied.
6547 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6548 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6549 float mHScale=1, mVScale=1;
6550 float mLastHScale=1, mLastVScale=1;
6551 final Matrix mTmpMatrix = new Matrix();
6552
6553 // "Real" frame that the application sees.
6554 final Rect mFrame = new Rect();
6555 final Rect mLastFrame = new Rect();
6556
6557 final Rect mContainingFrame = new Rect();
6558 final Rect mDisplayFrame = new Rect();
6559 final Rect mContentFrame = new Rect();
6560 final Rect mVisibleFrame = new Rect();
6561
6562 float mShownAlpha = 1;
6563 float mAlpha = 1;
6564 float mLastAlpha = 1;
6565
6566 // Set to true if, when the window gets displayed, it should perform
6567 // an enter animation.
6568 boolean mEnterAnimationPending;
6569
6570 // Currently running animation.
6571 boolean mAnimating;
6572 boolean mLocalAnimating;
6573 Animation mAnimation;
6574 boolean mAnimationIsEntrance;
6575 boolean mHasTransformation;
6576 boolean mHasLocalTransformation;
6577 final Transformation mTransformation = new Transformation();
6578
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006579 // If a window showing a wallpaper: the requested offset for the
6580 // wallpaper; if a wallpaper window: the currently applied offset.
6581 float mWallpaperX = -1;
6582 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006583
6584 // If a window showing a wallpaper: what fraction of the offset
6585 // range corresponds to a full virtual screen.
6586 float mWallpaperXStep = -1;
6587 float mWallpaperYStep = -1;
6588
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006589 // Wallpaper windows: pixels offset based on above variables.
6590 int mXOffset;
6591 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006593 // This is set after IWindowSession.relayout() has been called at
6594 // least once for the window. It allows us to detect the situation
6595 // where we don't yet have a surface, but should have one soon, so
6596 // we can give the window focus before waiting for the relayout.
6597 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006599 // This is set after the Surface has been created but before the
6600 // window has been drawn. During this time the surface is hidden.
6601 boolean mDrawPending;
6602
6603 // This is set after the window has finished drawing for the first
6604 // time but before its surface is shown. The surface will be
6605 // displayed when the next layout is run.
6606 boolean mCommitDrawPending;
6607
6608 // This is set during the time after the window's drawing has been
6609 // committed, and before its surface is actually shown. It is used
6610 // to delay showing the surface until all windows in a token are ready
6611 // to be shown.
6612 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614 // Set when the window has been shown in the screen the first time.
6615 boolean mHasDrawn;
6616
6617 // Currently running an exit animation?
6618 boolean mExiting;
6619
6620 // Currently on the mDestroySurface list?
6621 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006623 // Completely remove from window manager after exit animation?
6624 boolean mRemoveOnExit;
6625
6626 // Set when the orientation is changing and this window has not yet
6627 // been updated for the new orientation.
6628 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 // Is this window now (or just being) removed?
6631 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006632
Dianne Hackborn16064f92010-03-25 00:47:24 -07006633 // For debugging, this is the last information given to the surface flinger.
6634 boolean mSurfaceShown;
6635 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6636 int mSurfaceLayer;
6637 float mSurfaceAlpha;
6638
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006639 // Input channel
6640 InputChannel mInputChannel;
6641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006642 WindowState(Session s, IWindow c, WindowToken token,
6643 WindowState attachedWindow, WindowManager.LayoutParams a,
6644 int viewVisibility) {
6645 mSession = s;
6646 mClient = c;
6647 mToken = token;
6648 mAttrs.copyFrom(a);
6649 mViewVisibility = viewVisibility;
6650 DeathRecipient deathRecipient = new DeathRecipient();
6651 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006652 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 TAG, "Window " + this + " client=" + c.asBinder()
6654 + " token=" + token + " (" + mAttrs.token + ")");
6655 try {
6656 c.asBinder().linkToDeath(deathRecipient, 0);
6657 } catch (RemoteException e) {
6658 mDeathRecipient = null;
6659 mAttachedWindow = null;
6660 mLayoutAttached = false;
6661 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006662 mIsWallpaper = false;
6663 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 mBaseLayer = 0;
6665 mSubLayer = 0;
6666 return;
6667 }
6668 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006670 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6671 mAttrs.type <= LAST_SUB_WINDOW)) {
6672 // The multiplier here is to reserve space for multiple
6673 // windows in the same type layer.
6674 mBaseLayer = mPolicy.windowTypeToLayerLw(
6675 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6676 + TYPE_LAYER_OFFSET;
6677 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6678 mAttachedWindow = attachedWindow;
6679 mAttachedWindow.mChildWindows.add(this);
6680 mLayoutAttached = mAttrs.type !=
6681 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6682 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6683 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006684 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6685 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 } else {
6687 // The multiplier here is to reserve space for multiple
6688 // windows in the same type layer.
6689 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6690 * TYPE_LAYER_MULTIPLIER
6691 + TYPE_LAYER_OFFSET;
6692 mSubLayer = 0;
6693 mAttachedWindow = null;
6694 mLayoutAttached = false;
6695 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6696 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006697 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6698 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 }
6700
6701 WindowState appWin = this;
6702 while (appWin.mAttachedWindow != null) {
6703 appWin = mAttachedWindow;
6704 }
6705 WindowToken appToken = appWin.mToken;
6706 while (appToken.appWindowToken == null) {
6707 WindowToken parent = mTokenMap.get(appToken.token);
6708 if (parent == null || appToken == parent) {
6709 break;
6710 }
6711 appToken = parent;
6712 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006713 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 mAppToken = appToken.appWindowToken;
6715
6716 mSurface = null;
6717 mRequestedWidth = 0;
6718 mRequestedHeight = 0;
6719 mLastRequestedWidth = 0;
6720 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006721 mXOffset = 0;
6722 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 mLayer = 0;
6724 mAnimLayer = 0;
6725 mLastLayer = 0;
6726 }
6727
6728 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006729 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006730 TAG, "Attaching " + this + " token=" + mToken
6731 + ", list=" + mToken.windows);
6732 mSession.windowAddedLocked();
6733 }
6734
6735 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6736 mHaveFrame = true;
6737
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006738 final Rect container = mContainingFrame;
6739 container.set(pf);
6740
6741 final Rect display = mDisplayFrame;
6742 display.set(df);
6743
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006744 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006745 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006746 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6747 display.intersect(mCompatibleScreenFrame);
6748 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006749 }
6750
6751 final int pw = container.right - container.left;
6752 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753
6754 int w,h;
6755 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6756 w = mAttrs.width < 0 ? pw : mAttrs.width;
6757 h = mAttrs.height< 0 ? ph : mAttrs.height;
6758 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006759 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6760 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 }
Romain Guy06882f82009-06-10 13:36:04 -07006762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006763 final Rect content = mContentFrame;
6764 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006766 final Rect visible = mVisibleFrame;
6767 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006770 final int fw = frame.width();
6771 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6774 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6775
6776 Gravity.apply(mAttrs.gravity, w, h, container,
6777 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6778 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6779
6780 //System.out.println("Out: " + mFrame);
6781
6782 // Now make sure the window fits in the overall display.
6783 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 // Make sure the content and visible frames are inside of the
6786 // final window frame.
6787 if (content.left < frame.left) content.left = frame.left;
6788 if (content.top < frame.top) content.top = frame.top;
6789 if (content.right > frame.right) content.right = frame.right;
6790 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6791 if (visible.left < frame.left) visible.left = frame.left;
6792 if (visible.top < frame.top) visible.top = frame.top;
6793 if (visible.right > frame.right) visible.right = frame.right;
6794 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 final Rect contentInsets = mContentInsets;
6797 contentInsets.left = content.left-frame.left;
6798 contentInsets.top = content.top-frame.top;
6799 contentInsets.right = frame.right-content.right;
6800 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 final Rect visibleInsets = mVisibleInsets;
6803 visibleInsets.left = visible.left-frame.left;
6804 visibleInsets.top = visible.top-frame.top;
6805 visibleInsets.right = frame.right-visible.right;
6806 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006807
Dianne Hackborn284ac932009-08-28 10:34:25 -07006808 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6809 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006810 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006811 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 if (localLOGV) {
6814 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6815 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006816 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 + mRequestedWidth + ", mRequestedheight="
6818 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6819 + "): frame=" + mFrame.toShortString()
6820 + " ci=" + contentInsets.toShortString()
6821 + " vi=" + visibleInsets.toShortString());
6822 //}
6823 }
6824 }
Romain Guy06882f82009-06-10 13:36:04 -07006825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 public Rect getFrameLw() {
6827 return mFrame;
6828 }
6829
6830 public Rect getShownFrameLw() {
6831 return mShownFrame;
6832 }
6833
6834 public Rect getDisplayFrameLw() {
6835 return mDisplayFrame;
6836 }
6837
6838 public Rect getContentFrameLw() {
6839 return mContentFrame;
6840 }
6841
6842 public Rect getVisibleFrameLw() {
6843 return mVisibleFrame;
6844 }
6845
6846 public boolean getGivenInsetsPendingLw() {
6847 return mGivenInsetsPending;
6848 }
6849
6850 public Rect getGivenContentInsetsLw() {
6851 return mGivenContentInsets;
6852 }
Romain Guy06882f82009-06-10 13:36:04 -07006853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 public Rect getGivenVisibleInsetsLw() {
6855 return mGivenVisibleInsets;
6856 }
Romain Guy06882f82009-06-10 13:36:04 -07006857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 public WindowManager.LayoutParams getAttrs() {
6859 return mAttrs;
6860 }
6861
6862 public int getSurfaceLayer() {
6863 return mLayer;
6864 }
Romain Guy06882f82009-06-10 13:36:04 -07006865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 public IApplicationToken getAppToken() {
6867 return mAppToken != null ? mAppToken.appToken : null;
6868 }
Jeff Brown349703e2010-06-22 01:27:15 -07006869
6870 public long getInputDispatchingTimeoutNanos() {
6871 return mAppToken != null
6872 ? mAppToken.inputDispatchingTimeoutNanos
6873 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875
6876 public boolean hasAppShownWindows() {
6877 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6878 }
6879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006881 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 TAG, "Setting animation in " + this + ": " + anim);
6883 mAnimating = false;
6884 mLocalAnimating = false;
6885 mAnimation = anim;
6886 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6887 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6888 }
6889
6890 public void clearAnimation() {
6891 if (mAnimation != null) {
6892 mAnimating = true;
6893 mLocalAnimating = false;
6894 mAnimation = null;
6895 }
6896 }
Romain Guy06882f82009-06-10 13:36:04 -07006897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 Surface createSurfaceLocked() {
6899 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006900 mReportDestroySurface = false;
6901 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 mDrawPending = true;
6903 mCommitDrawPending = false;
6904 mReadyToShow = false;
6905 if (mAppToken != null) {
6906 mAppToken.allDrawn = false;
6907 }
6908
6909 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006910 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 flags |= Surface.PUSH_BUFFERS;
6912 }
6913
6914 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6915 flags |= Surface.SECURE;
6916 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006917 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 TAG, "Creating surface in session "
6919 + mSession.mSurfaceSession + " window " + this
6920 + " w=" + mFrame.width()
6921 + " h=" + mFrame.height() + " format="
6922 + mAttrs.format + " flags=" + flags);
6923
6924 int w = mFrame.width();
6925 int h = mFrame.height();
6926 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
6927 // for a scaled surface, we always want the requested
6928 // size.
6929 w = mRequestedWidth;
6930 h = mRequestedHeight;
6931 }
6932
Romain Guy9825ec62009-10-01 00:58:09 -07006933 // Something is wrong and SurfaceFlinger will not like this,
6934 // try to revert to sane values
6935 if (w <= 0) w = 1;
6936 if (h <= 0) h = 1;
6937
Dianne Hackborn16064f92010-03-25 00:47:24 -07006938 mSurfaceShown = false;
6939 mSurfaceLayer = 0;
6940 mSurfaceAlpha = 1;
6941 mSurfaceX = 0;
6942 mSurfaceY = 0;
6943 mSurfaceW = w;
6944 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 try {
Romain Guyd10cd572010-10-10 13:33:22 -07006946 final boolean isHwAccelerated = (mAttrs.flags &
6947 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
6948 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
6949 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
6950 flags |= Surface.OPAQUE;
6951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07006953 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08006954 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07006955 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006956 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006957 + mSurface + " IN SESSION "
6958 + mSession.mSurfaceSession
6959 + ": pid=" + mSession.mPid + " format="
6960 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006961 + Integer.toHexString(flags)
6962 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006964 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 reclaimSomeSurfaceMemoryLocked(this, "create");
6966 return null;
6967 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006968 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 return null;
6970 }
Romain Guy06882f82009-06-10 13:36:04 -07006971
Joe Onorato8a9b2202010-02-26 18:56:32 -08006972 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 TAG, "Got surface: " + mSurface
6974 + ", set left=" + mFrame.left + " top=" + mFrame.top
6975 + ", animLayer=" + mAnimLayer);
6976 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006977 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006978 if (SHOW_TRANSACTIONS) logSurface(this,
6979 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
6980 mFrame.width() + "x" + mFrame.height() + "), layer=" +
6981 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006982 }
6983 Surface.openTransaction();
6984 try {
6985 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07006986 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07006987 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07006988 mSurface.setPosition(mSurfaceX, mSurfaceY);
6989 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006991 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006992 mSurface.hide();
6993 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006994 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 mSurface.setFlags(Surface.SURFACE_DITHER,
6996 Surface.SURFACE_DITHER);
6997 }
6998 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006999 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7001 }
7002 mLastHidden = true;
7003 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007004 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 Surface.closeTransaction();
7006 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007007 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007008 TAG, "Created surface " + this);
7009 }
7010 return mSurface;
7011 }
Romain Guy06882f82009-06-10 13:36:04 -07007012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007013 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007014 if (mAppToken != null && this == mAppToken.startingWindow) {
7015 mAppToken.startingDisplayed = false;
7016 }
Romain Guy06882f82009-06-10 13:36:04 -07007017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007019 mDrawPending = false;
7020 mCommitDrawPending = false;
7021 mReadyToShow = false;
7022
7023 int i = mChildWindows.size();
7024 while (i > 0) {
7025 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007026 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007027 c.mAttachedHidden = true;
7028 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007029
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007030 if (mReportDestroySurface) {
7031 mReportDestroySurface = false;
7032 mSurfacePendingDestroy = true;
7033 try {
7034 mClient.dispatchGetNewSurface();
7035 // We'll really destroy on the next time around.
7036 return;
7037 } catch (RemoteException e) {
7038 }
7039 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007042 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007043 RuntimeException e = null;
7044 if (!HIDE_STACK_CRAWLS) {
7045 e = new RuntimeException();
7046 e.fillInStackTrace();
7047 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007048 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007049 + mSurface + ", session " + mSession, e);
7050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007051 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007052 RuntimeException e = null;
7053 if (!HIDE_STACK_CRAWLS) {
7054 e = new RuntimeException();
7055 e.fillInStackTrace();
7056 }
7057 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007058 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007059 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007061 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007062 + " surface " + mSurface + " session " + mSession
7063 + ": " + e.toString());
7064 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007065
Dianne Hackborn16064f92010-03-25 00:47:24 -07007066 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 }
7069 }
7070
7071 boolean finishDrawingLocked() {
7072 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007073 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 TAG, "finishDrawingLocked: " + mSurface);
7075 mCommitDrawPending = true;
7076 mDrawPending = false;
7077 return true;
7078 }
7079 return false;
7080 }
7081
7082 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007083 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007084 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007086 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 }
7088 mCommitDrawPending = false;
7089 mReadyToShow = true;
7090 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7091 final AppWindowToken atoken = mAppToken;
7092 if (atoken == null || atoken.allDrawn || starting) {
7093 performShowLocked();
7094 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007095 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007096 }
7097
7098 // This must be called while inside a transaction.
7099 boolean performShowLocked() {
7100 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007101 RuntimeException e = null;
7102 if (!HIDE_STACK_CRAWLS) {
7103 e = new RuntimeException();
7104 e.fillInStackTrace();
7105 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007106 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7108 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7109 }
7110 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007111 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7112 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007113 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 + " during animation: policyVis=" + mPolicyVisibility
7115 + " attHidden=" + mAttachedHidden
7116 + " tok.hiddenRequested="
7117 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007118 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007119 + (mAppToken != null ? mAppToken.hidden : false)
7120 + " animating=" + mAnimating
7121 + " tok animating="
7122 + (mAppToken != null ? mAppToken.animating : false));
7123 if (!showSurfaceRobustlyLocked(this)) {
7124 return false;
7125 }
7126 mLastAlpha = -1;
7127 mHasDrawn = true;
7128 mLastHidden = false;
7129 mReadyToShow = false;
7130 enableScreenIfNeededLocked();
7131
7132 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 int i = mChildWindows.size();
7135 while (i > 0) {
7136 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007137 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007138 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007139 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007140 if (c.mSurface != null) {
7141 c.performShowLocked();
7142 // It hadn't been shown, which means layout not
7143 // performed on it, so now we want to make sure to
7144 // do a layout. If called from within the transaction
7145 // loop, this will cause it to restart with a new
7146 // layout.
7147 mLayoutNeeded = true;
7148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 }
7150 }
Romain Guy06882f82009-06-10 13:36:04 -07007151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007152 if (mAttrs.type != TYPE_APPLICATION_STARTING
7153 && mAppToken != null) {
7154 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007155
Dianne Hackborn248b1882009-09-16 16:46:44 -07007156 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007157 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007158 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007159 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007160 // If this initial window is animating, stop it -- we
7161 // will do an animation to reveal it from behind the
7162 // starting window, so there is no need for it to also
7163 // be doing its own stuff.
7164 if (mAnimation != null) {
7165 mAnimation = null;
7166 // Make sure we clean up the animation.
7167 mAnimating = true;
7168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007169 mFinishedStarting.add(mAppToken);
7170 mH.sendEmptyMessage(H.FINISHED_STARTING);
7171 }
7172 mAppToken.updateReportedVisibilityLocked();
7173 }
7174 }
7175 return true;
7176 }
Romain Guy06882f82009-06-10 13:36:04 -07007177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007178 // This must be called while inside a transaction. Returns true if
7179 // there is more animation to run.
7180 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007181 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7185 mHasTransformation = true;
7186 mHasLocalTransformation = true;
7187 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007188 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 TAG, "Starting animation in " + this +
7190 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7191 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7192 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7193 mAnimation.setStartTime(currentTime);
7194 mLocalAnimating = true;
7195 mAnimating = true;
7196 }
7197 mTransformation.clear();
7198 final boolean more = mAnimation.getTransformation(
7199 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007200 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007201 TAG, "Stepped animation in " + this +
7202 ": more=" + more + ", xform=" + mTransformation);
7203 if (more) {
7204 // we're not done!
7205 return true;
7206 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007207 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007208 TAG, "Finished animation in " + this +
7209 " @ " + currentTime);
7210 mAnimation = null;
7211 //WindowManagerService.this.dump();
7212 }
7213 mHasLocalTransformation = false;
7214 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007215 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 // When our app token is animating, we kind-of pretend like
7217 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7218 // part of this check means that we will only do this if
7219 // our window is not currently exiting, or it is not
7220 // locally animating itself. The idea being that one that
7221 // is exiting and doing a local animation should be removed
7222 // once that animation is done.
7223 mAnimating = true;
7224 mHasTransformation = true;
7225 mTransformation.clear();
7226 return false;
7227 } else if (mHasTransformation) {
7228 // Little trick to get through the path below to act like
7229 // we have finished an animation.
7230 mAnimating = true;
7231 } else if (isAnimating()) {
7232 mAnimating = true;
7233 }
7234 } else if (mAnimation != null) {
7235 // If the display is frozen, and there is a pending animation,
7236 // clear it and make sure we run the cleanup code.
7237 mAnimating = true;
7238 mLocalAnimating = true;
7239 mAnimation = null;
7240 }
Romain Guy06882f82009-06-10 13:36:04 -07007241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007242 if (!mAnimating && !mLocalAnimating) {
7243 return false;
7244 }
7245
Joe Onorato8a9b2202010-02-26 18:56:32 -08007246 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 TAG, "Animation done in " + this + ": exiting=" + mExiting
7248 + ", reportedVisible="
7249 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007251 mAnimating = false;
7252 mLocalAnimating = false;
7253 mAnimation = null;
7254 mAnimLayer = mLayer;
7255 if (mIsImWindow) {
7256 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007257 } else if (mIsWallpaper) {
7258 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007260 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261 + " anim layer: " + mAnimLayer);
7262 mHasTransformation = false;
7263 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007264 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7265 if (DEBUG_VISIBILITY) {
7266 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7267 + mPolicyVisibilityAfterAnim);
7268 }
7269 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7270 if (!mPolicyVisibility) {
7271 if (mCurrentFocus == this) {
7272 mFocusMayChange = true;
7273 }
7274 // Window is no longer visible -- make sure if we were waiting
7275 // for it to be displayed before enabling the display, that
7276 // we allow the display to be enabled now.
7277 enableScreenIfNeededLocked();
7278 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007280 mTransformation.clear();
7281 if (mHasDrawn
7282 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7283 && mAppToken != null
7284 && mAppToken.firstWindowDrawn
7285 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007286 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 + mToken + ": first real window done animating");
7288 mFinishedStarting.add(mAppToken);
7289 mH.sendEmptyMessage(H.FINISHED_STARTING);
7290 }
Romain Guy06882f82009-06-10 13:36:04 -07007291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007292 finishExit();
7293
7294 if (mAppToken != null) {
7295 mAppToken.updateReportedVisibilityLocked();
7296 }
7297
7298 return false;
7299 }
7300
7301 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007302 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007303 TAG, "finishExit in " + this
7304 + ": exiting=" + mExiting
7305 + " remove=" + mRemoveOnExit
7306 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 final int N = mChildWindows.size();
7309 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007310 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 }
Romain Guy06882f82009-06-10 13:36:04 -07007312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 if (!mExiting) {
7314 return;
7315 }
Romain Guy06882f82009-06-10 13:36:04 -07007316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007317 if (isWindowAnimating()) {
7318 return;
7319 }
7320
Joe Onorato8a9b2202010-02-26 18:56:32 -08007321 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007322 TAG, "Exit animation finished in " + this
7323 + ": remove=" + mRemoveOnExit);
7324 if (mSurface != null) {
7325 mDestroySurface.add(this);
7326 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007327 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007328 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 try {
7330 mSurface.hide();
7331 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007332 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007333 }
7334 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 }
7336 mExiting = false;
7337 if (mRemoveOnExit) {
7338 mPendingRemove.add(this);
7339 mRemoveOnExit = false;
7340 }
7341 }
Romain Guy06882f82009-06-10 13:36:04 -07007342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7344 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7345 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7346 if (dtdx < -.000001f || dtdx > .000001f) return false;
7347 if (dsdy < -.000001f || dsdy > .000001f) return false;
7348 return true;
7349 }
Romain Guy06882f82009-06-10 13:36:04 -07007350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007351 void computeShownFrameLocked() {
7352 final boolean selfTransformation = mHasLocalTransformation;
7353 Transformation attachedTransformation =
7354 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7355 ? mAttachedWindow.mTransformation : null;
7356 Transformation appTransformation =
7357 (mAppToken != null && mAppToken.hasTransformation)
7358 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007359
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007360 // Wallpapers are animated based on the "real" window they
7361 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007362 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007363 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007364 if (mWallpaperTarget.mHasLocalTransformation &&
7365 mWallpaperTarget.mAnimation != null &&
7366 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007367 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007368 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007369 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007370 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007371 }
7372 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007373 mWallpaperTarget.mAppToken.hasTransformation &&
7374 mWallpaperTarget.mAppToken.animation != null &&
7375 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007376 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007377 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007378 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007379 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007380 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007381 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007383 if (selfTransformation || attachedTransformation != null
7384 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007385 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 final Rect frame = mFrame;
7387 final float tmpFloats[] = mTmpFloats;
7388 final Matrix tmpMatrix = mTmpMatrix;
7389
7390 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007391 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007393 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007395 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007396 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007397 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007398 }
7399 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007400 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007401 }
7402
7403 // "convert" it into SurfaceFlinger's format
7404 // (a 2x2 matrix + an offset)
7405 // Here we must not transform the position of the surface
7406 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007407 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 tmpMatrix.getValues(tmpFloats);
7410 mDsDx = tmpFloats[Matrix.MSCALE_X];
7411 mDtDx = tmpFloats[Matrix.MSKEW_X];
7412 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7413 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007414 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7415 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007416 int w = frame.width();
7417 int h = frame.height();
7418 mShownFrame.set(x, y, x+w, y+h);
7419
7420 // Now set the alpha... but because our current hardware
7421 // can't do alpha transformation on a non-opaque surface,
7422 // turn it off if we are running an animation that is also
7423 // transforming since it is more important to have that
7424 // animation be smooth.
7425 mShownAlpha = mAlpha;
7426 if (!mLimitedAlphaCompositing
7427 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7428 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7429 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007430 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 if (selfTransformation) {
7432 mShownAlpha *= mTransformation.getAlpha();
7433 }
7434 if (attachedTransformation != null) {
7435 mShownAlpha *= attachedTransformation.getAlpha();
7436 }
7437 if (appTransformation != null) {
7438 mShownAlpha *= appTransformation.getAlpha();
7439 }
7440 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007441 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007442 }
Romain Guy06882f82009-06-10 13:36:04 -07007443
Joe Onorato8a9b2202010-02-26 18:56:32 -08007444 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007445 TAG, "Continuing animation in " + this +
7446 ": " + mShownFrame +
7447 ", alpha=" + mTransformation.getAlpha());
7448 return;
7449 }
Romain Guy06882f82009-06-10 13:36:04 -07007450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007452 if (mXOffset != 0 || mYOffset != 0) {
7453 mShownFrame.offset(mXOffset, mYOffset);
7454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 mShownAlpha = mAlpha;
7456 mDsDx = 1;
7457 mDtDx = 0;
7458 mDsDy = 0;
7459 mDtDy = 1;
7460 }
Romain Guy06882f82009-06-10 13:36:04 -07007461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 /**
7463 * Is this window visible? It is not visible if there is no
7464 * surface, or we are in the process of running an exit animation
7465 * that will remove the surface, or its app token has been hidden.
7466 */
7467 public boolean isVisibleLw() {
7468 final AppWindowToken atoken = mAppToken;
7469 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7470 && (atoken == null || !atoken.hiddenRequested)
7471 && !mExiting && !mDestroying;
7472 }
7473
7474 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007475 * Like {@link #isVisibleLw}, but also counts a window that is currently
7476 * "hidden" behind the keyguard as visible. This allows us to apply
7477 * things like window flags that impact the keyguard.
7478 * XXX I am starting to think we need to have ANOTHER visibility flag
7479 * for this "hidden behind keyguard" state rather than overloading
7480 * mPolicyVisibility. Ungh.
7481 */
7482 public boolean isVisibleOrBehindKeyguardLw() {
7483 final AppWindowToken atoken = mAppToken;
7484 return mSurface != null && !mAttachedHidden
7485 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007486 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007487 && !mExiting && !mDestroying;
7488 }
7489
7490 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 * Is this window visible, ignoring its app token? It is not visible
7492 * if there is no surface, or we are in the process of running an exit animation
7493 * that will remove the surface.
7494 */
7495 public boolean isWinVisibleLw() {
7496 final AppWindowToken atoken = mAppToken;
7497 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7498 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7499 && !mExiting && !mDestroying;
7500 }
7501
7502 /**
7503 * The same as isVisible(), but follows the current hidden state of
7504 * the associated app token, not the pending requested hidden state.
7505 */
7506 boolean isVisibleNow() {
7507 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007508 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 }
7510
7511 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007512 * Can this window possibly be a drag/drop target? The test here is
7513 * a combination of the above "visible now" with the check that the
7514 * Input Manager uses when discarding windows from input consideration.
7515 */
7516 boolean isPotentialDragTarget() {
7517 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7518 }
7519
7520 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521 * Same as isVisible(), but we also count it as visible between the
7522 * call to IWindowSession.add() and the first relayout().
7523 */
7524 boolean isVisibleOrAdding() {
7525 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007526 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7528 && mPolicyVisibility && !mAttachedHidden
7529 && (atoken == null || !atoken.hiddenRequested)
7530 && !mExiting && !mDestroying;
7531 }
7532
7533 /**
7534 * Is this window currently on-screen? It is on-screen either if it
7535 * is visible or it is currently running an animation before no longer
7536 * being visible.
7537 */
7538 boolean isOnScreen() {
7539 final AppWindowToken atoken = mAppToken;
7540 if (atoken != null) {
7541 return mSurface != null && mPolicyVisibility && !mDestroying
7542 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007543 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007544 } else {
7545 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007546 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007547 }
7548 }
Romain Guy06882f82009-06-10 13:36:04 -07007549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007550 /**
7551 * Like isOnScreen(), but we don't return true if the window is part
7552 * of a transition that has not yet been started.
7553 */
7554 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007555 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007556 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007557 return false;
7558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007560 final boolean animating = atoken != null
7561 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007562 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007563 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7564 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007565 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 }
7567
7568 /** Is the window or its container currently animating? */
7569 boolean isAnimating() {
7570 final WindowState attached = mAttachedWindow;
7571 final AppWindowToken atoken = mAppToken;
7572 return mAnimation != null
7573 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007574 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007575 (atoken.animation != null
7576 || atoken.inPendingTransaction));
7577 }
7578
7579 /** Is this window currently animating? */
7580 boolean isWindowAnimating() {
7581 return mAnimation != null;
7582 }
7583
7584 /**
7585 * Like isOnScreen, but returns false if the surface hasn't yet
7586 * been drawn.
7587 */
7588 public boolean isDisplayedLw() {
7589 final AppWindowToken atoken = mAppToken;
7590 return mSurface != null && mPolicyVisibility && !mDestroying
7591 && !mDrawPending && !mCommitDrawPending
7592 && ((!mAttachedHidden &&
7593 (atoken == null || !atoken.hiddenRequested))
7594 || mAnimating);
7595 }
7596
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007597 /**
7598 * Returns true if the window has a surface that it has drawn a
7599 * complete UI in to.
7600 */
7601 public boolean isDrawnLw() {
7602 final AppWindowToken atoken = mAppToken;
7603 return mSurface != null && !mDestroying
7604 && !mDrawPending && !mCommitDrawPending;
7605 }
7606
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007607 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007608 * Return true if the window is opaque and fully drawn. This indicates
7609 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007610 */
7611 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007612 return (mAttrs.format == PixelFormat.OPAQUE
7613 || mAttrs.type == TYPE_WALLPAPER)
7614 && mSurface != null && mAnimation == null
7615 && (mAppToken == null || mAppToken.animation == null)
7616 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007617 }
7618
7619 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7620 return
7621 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007622 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7623 // only if it's visible
7624 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007625 // and only if the application fills the compatible screen
7626 mFrame.left <= mCompatibleScreenFrame.left &&
7627 mFrame.top <= mCompatibleScreenFrame.top &&
7628 mFrame.right >= mCompatibleScreenFrame.right &&
7629 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007630 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007631 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007632 }
7633
7634 boolean isFullscreen(int screenWidth, int screenHeight) {
7635 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007636 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 }
7638
7639 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007640 disposeInputChannel();
7641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007642 if (mAttachedWindow != null) {
7643 mAttachedWindow.mChildWindows.remove(this);
7644 }
7645 destroySurfaceLocked();
7646 mSession.windowRemovedLocked();
7647 try {
7648 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7649 } catch (RuntimeException e) {
7650 // Ignore if it has already been removed (usually because
7651 // we are doing this as part of processing a death note.)
7652 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007653 }
7654
7655 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007656 if (mInputChannel != null) {
7657 mInputManager.unregisterInputChannel(mInputChannel);
7658
7659 mInputChannel.dispose();
7660 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 }
7663
7664 private class DeathRecipient implements IBinder.DeathRecipient {
7665 public void binderDied() {
7666 try {
7667 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007668 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007669 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007670 if (win != null) {
7671 removeWindowLocked(mSession, win);
7672 }
7673 }
7674 } catch (IllegalArgumentException ex) {
7675 // This will happen if the window has already been
7676 // removed.
7677 }
7678 }
7679 }
7680
7681 /** Returns true if this window desires key events. */
7682 public final boolean canReceiveKeys() {
7683 return isVisibleOrAdding()
7684 && (mViewVisibility == View.VISIBLE)
7685 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7686 }
7687
7688 public boolean hasDrawnLw() {
7689 return mHasDrawn;
7690 }
7691
7692 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007693 return showLw(doAnimation, true);
7694 }
7695
7696 boolean showLw(boolean doAnimation, boolean requestAnim) {
7697 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7698 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007700 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007701 if (doAnimation) {
7702 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7703 + mPolicyVisibility + " mAnimation=" + mAnimation);
7704 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7705 doAnimation = false;
7706 } else if (mPolicyVisibility && mAnimation == null) {
7707 // Check for the case where we are currently visible and
7708 // not animating; we do not want to do animation at such a
7709 // point to become visible when we already are.
7710 doAnimation = false;
7711 }
7712 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007713 mPolicyVisibility = true;
7714 mPolicyVisibilityAfterAnim = true;
7715 if (doAnimation) {
7716 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7717 }
7718 if (requestAnim) {
7719 requestAnimationLocked(0);
7720 }
7721 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007722 }
7723
7724 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007725 return hideLw(doAnimation, true);
7726 }
7727
7728 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007729 if (doAnimation) {
7730 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7731 doAnimation = false;
7732 }
7733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007734 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7735 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007736 if (!current) {
7737 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007738 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007739 if (doAnimation) {
7740 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7741 if (mAnimation == null) {
7742 doAnimation = false;
7743 }
7744 }
7745 if (doAnimation) {
7746 mPolicyVisibilityAfterAnim = false;
7747 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007748 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007749 mPolicyVisibilityAfterAnim = false;
7750 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007751 // Window is no longer visible -- make sure if we were waiting
7752 // for it to be displayed before enabling the display, that
7753 // we allow the display to be enabled now.
7754 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007755 if (mCurrentFocus == this) {
7756 mFocusMayChange = true;
7757 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007758 }
7759 if (requestAnim) {
7760 requestAnimationLocked(0);
7761 }
7762 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007763 }
7764
7765 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007766 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7767 pw.print(" mClient="); pw.println(mClient.asBinder());
7768 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7769 if (mAttachedWindow != null || mLayoutAttached) {
7770 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7771 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7772 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007773 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7774 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7775 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007776 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7777 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007778 }
7779 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7780 pw.print(" mSubLayer="); pw.print(mSubLayer);
7781 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7782 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7783 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7784 pw.print("="); pw.print(mAnimLayer);
7785 pw.print(" mLastLayer="); pw.println(mLastLayer);
7786 if (mSurface != null) {
7787 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007788 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7789 pw.print(" layer="); pw.print(mSurfaceLayer);
7790 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7791 pw.print(" rect=("); pw.print(mSurfaceX);
7792 pw.print(","); pw.print(mSurfaceY);
7793 pw.print(") "); pw.print(mSurfaceW);
7794 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007795 }
7796 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7797 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7798 if (mAppToken != null) {
7799 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7800 }
7801 if (mTargetAppToken != null) {
7802 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7803 }
7804 pw.print(prefix); pw.print("mViewVisibility=0x");
7805 pw.print(Integer.toHexString(mViewVisibility));
7806 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007807 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7808 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007809 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7810 pw.print(prefix); pw.print("mPolicyVisibility=");
7811 pw.print(mPolicyVisibility);
7812 pw.print(" mPolicyVisibilityAfterAnim=");
7813 pw.print(mPolicyVisibilityAfterAnim);
7814 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7815 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007816 if (!mRelayoutCalled) {
7817 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7818 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007819 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007820 pw.print(" h="); pw.print(mRequestedHeight);
7821 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007822 if (mXOffset != 0 || mYOffset != 0) {
7823 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7824 pw.print(" y="); pw.println(mYOffset);
7825 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007826 pw.print(prefix); pw.print("mGivenContentInsets=");
7827 mGivenContentInsets.printShortString(pw);
7828 pw.print(" mGivenVisibleInsets=");
7829 mGivenVisibleInsets.printShortString(pw);
7830 pw.println();
7831 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7832 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7833 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7834 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007835 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007836 pw.print(prefix); pw.print("mShownFrame=");
7837 mShownFrame.printShortString(pw);
7838 pw.print(" last="); mLastShownFrame.printShortString(pw);
7839 pw.println();
7840 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7841 pw.print(" last="); mLastFrame.printShortString(pw);
7842 pw.println();
7843 pw.print(prefix); pw.print("mContainingFrame=");
7844 mContainingFrame.printShortString(pw);
7845 pw.print(" mDisplayFrame=");
7846 mDisplayFrame.printShortString(pw);
7847 pw.println();
7848 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7849 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7850 pw.println();
7851 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7852 pw.print(" last="); mLastContentInsets.printShortString(pw);
7853 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7854 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7855 pw.println();
7856 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7857 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7858 pw.print(" mAlpha="); pw.print(mAlpha);
7859 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7860 }
7861 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7862 || mAnimation != null) {
7863 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7864 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7865 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7866 pw.print(" mAnimation="); pw.println(mAnimation);
7867 }
7868 if (mHasTransformation || mHasLocalTransformation) {
7869 pw.print(prefix); pw.print("XForm: has=");
7870 pw.print(mHasTransformation);
7871 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7872 pw.print(" "); mTransformation.printShortString(pw);
7873 pw.println();
7874 }
7875 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7876 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7877 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7878 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7879 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7880 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7881 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7882 pw.print(" mDestroying="); pw.print(mDestroying);
7883 pw.print(" mRemoved="); pw.println(mRemoved);
7884 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007885 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007886 pw.print(prefix); pw.print("mOrientationChanging=");
7887 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007888 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7889 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007890 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007891 if (mHScale != 1 || mVScale != 1) {
7892 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7893 pw.print(" mVScale="); pw.println(mVScale);
7894 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007895 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007896 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7897 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7898 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007899 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7900 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7901 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007903 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007904
7905 String makeInputChannelName() {
7906 return Integer.toHexString(System.identityHashCode(this))
7907 + " " + mAttrs.getTitle();
7908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909
7910 @Override
7911 public String toString() {
7912 return "Window{"
7913 + Integer.toHexString(System.identityHashCode(this))
7914 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7915 }
7916 }
Romain Guy06882f82009-06-10 13:36:04 -07007917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007918 // -------------------------------------------------------------
7919 // Window Token State
7920 // -------------------------------------------------------------
7921
7922 class WindowToken {
7923 // The actual token.
7924 final IBinder token;
7925
7926 // The type of window this token is for, as per WindowManager.LayoutParams.
7927 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07007928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007929 // Set if this token was explicitly added by a client, so should
7930 // not be removed when all windows are removed.
7931 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07007932
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007933 // For printing.
7934 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07007935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 // If this is an AppWindowToken, this is non-null.
7937 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07007938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 // All of the windows associated with this token.
7940 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
7941
7942 // Is key dispatching paused for this token?
7943 boolean paused = false;
7944
7945 // Should this token's windows be hidden?
7946 boolean hidden;
7947
7948 // Temporary for finding which tokens no longer have visible windows.
7949 boolean hasVisible;
7950
Dianne Hackborna8f60182009-09-01 19:01:50 -07007951 // Set to true when this token is in a pending transaction where it
7952 // will be shown.
7953 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007954
Dianne Hackborna8f60182009-09-01 19:01:50 -07007955 // Set to true when this token is in a pending transaction where it
7956 // will be hidden.
7957 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007958
Dianne Hackborna8f60182009-09-01 19:01:50 -07007959 // Set to true when this token is in a pending transaction where its
7960 // windows will be put to the bottom of the list.
7961 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007962
Dianne Hackborna8f60182009-09-01 19:01:50 -07007963 // Set to true when this token is in a pending transaction where its
7964 // windows will be put to the top of the list.
7965 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 WindowToken(IBinder _token, int type, boolean _explicit) {
7968 token = _token;
7969 windowType = type;
7970 explicit = _explicit;
7971 }
7972
7973 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007974 pw.print(prefix); pw.print("token="); pw.println(token);
7975 pw.print(prefix); pw.print("windows="); pw.println(windows);
7976 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
7977 pw.print(" hidden="); pw.print(hidden);
7978 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007979 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
7980 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
7981 pw.print(" waitingToHide="); pw.print(waitingToHide);
7982 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
7983 pw.print(" sendingToTop="); pw.println(sendingToTop);
7984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 }
7986
7987 @Override
7988 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007989 if (stringName == null) {
7990 StringBuilder sb = new StringBuilder();
7991 sb.append("WindowToken{");
7992 sb.append(Integer.toHexString(System.identityHashCode(this)));
7993 sb.append(" token="); sb.append(token); sb.append('}');
7994 stringName = sb.toString();
7995 }
7996 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007997 }
7998 };
7999
8000 class AppWindowToken extends WindowToken {
8001 // Non-null only for application tokens.
8002 final IApplicationToken appToken;
8003
8004 // All of the windows and child windows that are included in this
8005 // application token. Note this list is NOT sorted!
8006 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8007
8008 int groupId = -1;
8009 boolean appFullscreen;
8010 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008011
8012 // The input dispatching timeout for this application token in nanoseconds.
8013 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 // These are used for determining when all windows associated with
8016 // an activity have been drawn, so they can be made visible together
8017 // at the same time.
8018 int lastTransactionSequence = mTransactionSequence-1;
8019 int numInterestingWindows;
8020 int numDrawnWindows;
8021 boolean inPendingTransaction;
8022 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 // Is this token going to be hidden in a little while? If so, it
8025 // won't be taken into account for setting the screen orientation.
8026 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 // Is this window's surface needed? This is almost like hidden, except
8029 // it will sometimes be true a little earlier: when the token has
8030 // been shown, but is still waiting for its app transition to execute
8031 // before making its windows shown.
8032 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 // Have we told the window clients to hide themselves?
8035 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 // Last visibility state we reported to the app token.
8038 boolean reportedVisible;
8039
8040 // Set to true when the token has been removed from the window mgr.
8041 boolean removed;
8042
8043 // Have we been asked to have this token keep the screen frozen?
8044 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008046 boolean animating;
8047 Animation animation;
8048 boolean hasTransformation;
8049 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 // Offset to the window of all layers in the token, for use by
8052 // AppWindowToken animations.
8053 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 // Information about an application starting window if displayed.
8056 StartingData startingData;
8057 WindowState startingWindow;
8058 View startingView;
8059 boolean startingDisplayed;
8060 boolean startingMoved;
8061 boolean firstWindowDrawn;
8062
8063 AppWindowToken(IApplicationToken _token) {
8064 super(_token.asBinder(),
8065 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8066 appWindowToken = this;
8067 appToken = _token;
8068 }
Romain Guy06882f82009-06-10 13:36:04 -07008069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008070 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008071 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008072 TAG, "Setting animation in " + this + ": " + anim);
8073 animation = anim;
8074 animating = false;
8075 anim.restrictDuration(MAX_ANIMATION_DURATION);
8076 anim.scaleCurrentDuration(mTransitionAnimationScale);
8077 int zorder = anim.getZAdjustment();
8078 int adj = 0;
8079 if (zorder == Animation.ZORDER_TOP) {
8080 adj = TYPE_LAYER_OFFSET;
8081 } else if (zorder == Animation.ZORDER_BOTTOM) {
8082 adj = -TYPE_LAYER_OFFSET;
8083 }
Romain Guy06882f82009-06-10 13:36:04 -07008084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008085 if (animLayerAdjustment != adj) {
8086 animLayerAdjustment = adj;
8087 updateLayers();
8088 }
8089 }
Romain Guy06882f82009-06-10 13:36:04 -07008090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 public void setDummyAnimation() {
8092 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008093 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 TAG, "Setting dummy animation in " + this);
8095 animation = sDummyAnimation;
8096 }
8097 }
8098
8099 public void clearAnimation() {
8100 if (animation != null) {
8101 animation = null;
8102 animating = true;
8103 }
8104 }
Romain Guy06882f82009-06-10 13:36:04 -07008105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008106 void updateLayers() {
8107 final int N = allAppWindows.size();
8108 final int adj = animLayerAdjustment;
8109 for (int i=0; i<N; i++) {
8110 WindowState w = allAppWindows.get(i);
8111 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008112 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008113 + w.mAnimLayer);
8114 if (w == mInputMethodTarget) {
8115 setInputMethodAnimLayerAdjustment(adj);
8116 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008117 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008118 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 }
8121 }
Romain Guy06882f82009-06-10 13:36:04 -07008122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008123 void sendAppVisibilityToClients() {
8124 final int N = allAppWindows.size();
8125 for (int i=0; i<N; i++) {
8126 WindowState win = allAppWindows.get(i);
8127 if (win == startingWindow && clientHidden) {
8128 // Don't hide the starting window.
8129 continue;
8130 }
8131 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008132 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 "Setting visibility of " + win + ": " + (!clientHidden));
8134 win.mClient.dispatchAppVisibility(!clientHidden);
8135 } catch (RemoteException e) {
8136 }
8137 }
8138 }
Romain Guy06882f82009-06-10 13:36:04 -07008139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 void showAllWindowsLocked() {
8141 final int NW = allAppWindows.size();
8142 for (int i=0; i<NW; i++) {
8143 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008144 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008145 "performing show on: " + w);
8146 w.performShowLocked();
8147 }
8148 }
Romain Guy06882f82009-06-10 13:36:04 -07008149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 // This must be called while inside a transaction.
8151 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008152 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 if (animation == sDummyAnimation) {
8156 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008157 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158 // when it is really time to animate, this will be set to
8159 // a real animation and the next call will execute normally.
8160 return false;
8161 }
Romain Guy06882f82009-06-10 13:36:04 -07008162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8164 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008165 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 TAG, "Starting animation in " + this +
8167 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8168 + " scale=" + mTransitionAnimationScale
8169 + " allDrawn=" + allDrawn + " animating=" + animating);
8170 animation.initialize(dw, dh, dw, dh);
8171 animation.setStartTime(currentTime);
8172 animating = true;
8173 }
8174 transformation.clear();
8175 final boolean more = animation.getTransformation(
8176 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008177 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008178 TAG, "Stepped animation in " + this +
8179 ": more=" + more + ", xform=" + transformation);
8180 if (more) {
8181 // we're done!
8182 hasTransformation = true;
8183 return true;
8184 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008185 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186 TAG, "Finished animation in " + this +
8187 " @ " + currentTime);
8188 animation = null;
8189 }
8190 } else if (animation != null) {
8191 // If the display is frozen, and there is a pending animation,
8192 // clear it and make sure we run the cleanup code.
8193 animating = true;
8194 animation = null;
8195 }
8196
8197 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 if (!animating) {
8200 return false;
8201 }
8202
8203 clearAnimation();
8204 animating = false;
8205 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8206 moveInputMethodWindowsIfNeededLocked(true);
8207 }
Romain Guy06882f82009-06-10 13:36:04 -07008208
Joe Onorato8a9b2202010-02-26 18:56:32 -08008209 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210 TAG, "Animation done in " + this
8211 + ": reportedVisible=" + reportedVisible);
8212
8213 transformation.clear();
8214 if (animLayerAdjustment != 0) {
8215 animLayerAdjustment = 0;
8216 updateLayers();
8217 }
Romain Guy06882f82009-06-10 13:36:04 -07008218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 final int N = windows.size();
8220 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008221 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222 }
8223 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008225 return false;
8226 }
8227
8228 void updateReportedVisibilityLocked() {
8229 if (appToken == null) {
8230 return;
8231 }
Romain Guy06882f82009-06-10 13:36:04 -07008232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008233 int numInteresting = 0;
8234 int numVisible = 0;
8235 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008236
Joe Onorato8a9b2202010-02-26 18:56:32 -08008237 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238 final int N = allAppWindows.size();
8239 for (int i=0; i<N; i++) {
8240 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008241 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008242 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008243 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8244 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008245 continue;
8246 }
8247 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008248 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008249 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008250 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008251 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008252 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008253 + " pv=" + win.mPolicyVisibility
8254 + " dp=" + win.mDrawPending
8255 + " cdp=" + win.mCommitDrawPending
8256 + " ah=" + win.mAttachedHidden
8257 + " th="
8258 + (win.mAppToken != null
8259 ? win.mAppToken.hiddenRequested : false)
8260 + " a=" + win.mAnimating);
8261 }
8262 }
8263 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008264 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 if (!win.isAnimating()) {
8266 numVisible++;
8267 }
8268 nowGone = false;
8269 } else if (win.isAnimating()) {
8270 nowGone = false;
8271 }
8272 }
Romain Guy06882f82009-06-10 13:36:04 -07008273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008274 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008275 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276 + numInteresting + " visible=" + numVisible);
8277 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008278 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008279 TAG, "Visibility changed in " + this
8280 + ": vis=" + nowVisible);
8281 reportedVisible = nowVisible;
8282 Message m = mH.obtainMessage(
8283 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8284 nowVisible ? 1 : 0,
8285 nowGone ? 1 : 0,
8286 this);
8287 mH.sendMessage(m);
8288 }
8289 }
Romain Guy06882f82009-06-10 13:36:04 -07008290
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008291 WindowState findMainWindow() {
8292 int j = windows.size();
8293 while (j > 0) {
8294 j--;
8295 WindowState win = windows.get(j);
8296 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8297 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8298 return win;
8299 }
8300 }
8301 return null;
8302 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 void dump(PrintWriter pw, String prefix) {
8305 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008306 if (appToken != null) {
8307 pw.print(prefix); pw.println("app=true");
8308 }
8309 if (allAppWindows.size() > 0) {
8310 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8311 }
8312 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008313 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008314 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8315 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8316 pw.print(" clientHidden="); pw.print(clientHidden);
8317 pw.print(" willBeHidden="); pw.print(willBeHidden);
8318 pw.print(" reportedVisible="); pw.println(reportedVisible);
8319 if (paused || freezingScreen) {
8320 pw.print(prefix); pw.print("paused="); pw.print(paused);
8321 pw.print(" freezingScreen="); pw.println(freezingScreen);
8322 }
8323 if (numInterestingWindows != 0 || numDrawnWindows != 0
8324 || inPendingTransaction || allDrawn) {
8325 pw.print(prefix); pw.print("numInterestingWindows=");
8326 pw.print(numInterestingWindows);
8327 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8328 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8329 pw.print(" allDrawn="); pw.println(allDrawn);
8330 }
8331 if (animating || animation != null) {
8332 pw.print(prefix); pw.print("animating="); pw.print(animating);
8333 pw.print(" animation="); pw.println(animation);
8334 }
8335 if (animLayerAdjustment != 0) {
8336 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8337 }
8338 if (hasTransformation) {
8339 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8340 pw.print(" transformation="); transformation.printShortString(pw);
8341 pw.println();
8342 }
8343 if (startingData != null || removed || firstWindowDrawn) {
8344 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8345 pw.print(" removed="); pw.print(removed);
8346 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8347 }
8348 if (startingWindow != null || startingView != null
8349 || startingDisplayed || startingMoved) {
8350 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8351 pw.print(" startingView="); pw.print(startingView);
8352 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8353 pw.print(" startingMoved"); pw.println(startingMoved);
8354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 }
8356
8357 @Override
8358 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008359 if (stringName == null) {
8360 StringBuilder sb = new StringBuilder();
8361 sb.append("AppWindowToken{");
8362 sb.append(Integer.toHexString(System.identityHashCode(this)));
8363 sb.append(" token="); sb.append(token); sb.append('}');
8364 stringName = sb.toString();
8365 }
8366 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008367 }
8368 }
Romain Guy06882f82009-06-10 13:36:04 -07008369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008370 // -------------------------------------------------------------
8371 // DummyAnimation
8372 // -------------------------------------------------------------
8373
8374 // This is an animation that does nothing: it just immediately finishes
8375 // itself every time it is called. It is used as a stub animation in cases
8376 // where we want to synchronize multiple things that may be animating.
8377 static final class DummyAnimation extends Animation {
8378 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8379 return false;
8380 }
8381 }
8382 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008384 // -------------------------------------------------------------
8385 // Async Handler
8386 // -------------------------------------------------------------
8387
8388 static final class StartingData {
8389 final String pkg;
8390 final int theme;
8391 final CharSequence nonLocalizedLabel;
8392 final int labelRes;
8393 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07008394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008395 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
8396 int _labelRes, int _icon) {
8397 pkg = _pkg;
8398 theme = _theme;
8399 nonLocalizedLabel = _nonLocalizedLabel;
8400 labelRes = _labelRes;
8401 icon = _icon;
8402 }
8403 }
8404
8405 private final class H extends Handler {
8406 public static final int REPORT_FOCUS_CHANGE = 2;
8407 public static final int REPORT_LOSING_FOCUS = 3;
8408 public static final int ANIMATE = 4;
8409 public static final int ADD_STARTING = 5;
8410 public static final int REMOVE_STARTING = 6;
8411 public static final int FINISHED_STARTING = 7;
8412 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008413 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8414 public static final int HOLD_SCREEN_CHANGED = 12;
8415 public static final int APP_TRANSITION_TIMEOUT = 13;
8416 public static final int PERSIST_ANIMATION_SCALE = 14;
8417 public static final int FORCE_GC = 15;
8418 public static final int ENABLE_SCREEN = 16;
8419 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008420 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008421 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008422 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008423 public static final int DRAG_END_TIMEOUT = 21;
Romain Guy06882f82009-06-10 13:36:04 -07008424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427 public H() {
8428 }
Romain Guy06882f82009-06-10 13:36:04 -07008429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008430 @Override
8431 public void handleMessage(Message msg) {
8432 switch (msg.what) {
8433 case REPORT_FOCUS_CHANGE: {
8434 WindowState lastFocus;
8435 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 synchronized(mWindowMap) {
8438 lastFocus = mLastFocus;
8439 newFocus = mCurrentFocus;
8440 if (lastFocus == newFocus) {
8441 // Focus is not changing, so nothing to do.
8442 return;
8443 }
8444 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008445 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008446 // + " to " + newFocus);
8447 if (newFocus != null && lastFocus != null
8448 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008449 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008450 mLosingFocus.add(lastFocus);
8451 lastFocus = null;
8452 }
8453 }
8454
8455 if (lastFocus != newFocus) {
8456 //System.out.println("Changing focus from " + lastFocus
8457 // + " to " + newFocus);
8458 if (newFocus != null) {
8459 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008460 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008461 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8462 } catch (RemoteException e) {
8463 // Ignore if process has died.
8464 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008465 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 }
8467
8468 if (lastFocus != null) {
8469 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008470 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008471 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8472 } catch (RemoteException e) {
8473 // Ignore if process has died.
8474 }
8475 }
8476 }
8477 } break;
8478
8479 case REPORT_LOSING_FOCUS: {
8480 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 synchronized(mWindowMap) {
8483 losers = mLosingFocus;
8484 mLosingFocus = new ArrayList<WindowState>();
8485 }
8486
8487 final int N = losers.size();
8488 for (int i=0; i<N; i++) {
8489 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008490 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008491 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8492 } catch (RemoteException e) {
8493 // Ignore if process has died.
8494 }
8495 }
8496 } break;
8497
8498 case ANIMATE: {
8499 synchronized(mWindowMap) {
8500 mAnimationPending = false;
8501 performLayoutAndPlaceSurfacesLocked();
8502 }
8503 } break;
8504
8505 case ADD_STARTING: {
8506 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8507 final StartingData sd = wtoken.startingData;
8508
8509 if (sd == null) {
8510 // Animation has been canceled... do nothing.
8511 return;
8512 }
Romain Guy06882f82009-06-10 13:36:04 -07008513
Joe Onorato8a9b2202010-02-26 18:56:32 -08008514 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008515 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 View view = null;
8518 try {
8519 view = mPolicy.addStartingWindow(
8520 wtoken.token, sd.pkg,
8521 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
8522 sd.icon);
8523 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008524 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 }
8526
8527 if (view != null) {
8528 boolean abort = false;
8529
8530 synchronized(mWindowMap) {
8531 if (wtoken.removed || wtoken.startingData == null) {
8532 // If the window was successfully added, then
8533 // we need to remove it.
8534 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008535 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 "Aborted starting " + wtoken
8537 + ": removed=" + wtoken.removed
8538 + " startingData=" + wtoken.startingData);
8539 wtoken.startingWindow = null;
8540 wtoken.startingData = null;
8541 abort = true;
8542 }
8543 } else {
8544 wtoken.startingView = view;
8545 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008546 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008547 "Added starting " + wtoken
8548 + ": startingWindow="
8549 + wtoken.startingWindow + " startingView="
8550 + wtoken.startingView);
8551 }
8552
8553 if (abort) {
8554 try {
8555 mPolicy.removeStartingWindow(wtoken.token, view);
8556 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008557 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008558 }
8559 }
8560 }
8561 } break;
8562
8563 case REMOVE_STARTING: {
8564 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8565 IBinder token = null;
8566 View view = null;
8567 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008568 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008569 + wtoken + ": startingWindow="
8570 + wtoken.startingWindow + " startingView="
8571 + wtoken.startingView);
8572 if (wtoken.startingWindow != null) {
8573 view = wtoken.startingView;
8574 token = wtoken.token;
8575 wtoken.startingData = null;
8576 wtoken.startingView = null;
8577 wtoken.startingWindow = null;
8578 }
8579 }
8580 if (view != null) {
8581 try {
8582 mPolicy.removeStartingWindow(token, view);
8583 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008584 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 }
8586 }
8587 } break;
8588
8589 case FINISHED_STARTING: {
8590 IBinder token = null;
8591 View view = null;
8592 while (true) {
8593 synchronized (mWindowMap) {
8594 final int N = mFinishedStarting.size();
8595 if (N <= 0) {
8596 break;
8597 }
8598 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8599
Joe Onorato8a9b2202010-02-26 18:56:32 -08008600 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 "Finished starting " + wtoken
8602 + ": startingWindow=" + wtoken.startingWindow
8603 + " startingView=" + wtoken.startingView);
8604
8605 if (wtoken.startingWindow == null) {
8606 continue;
8607 }
8608
8609 view = wtoken.startingView;
8610 token = wtoken.token;
8611 wtoken.startingData = null;
8612 wtoken.startingView = null;
8613 wtoken.startingWindow = null;
8614 }
8615
8616 try {
8617 mPolicy.removeStartingWindow(token, view);
8618 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008619 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008620 }
8621 }
8622 } break;
8623
8624 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8625 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8626
8627 boolean nowVisible = msg.arg1 != 0;
8628 boolean nowGone = msg.arg2 != 0;
8629
8630 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008631 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 TAG, "Reporting visible in " + wtoken
8633 + " visible=" + nowVisible
8634 + " gone=" + nowGone);
8635 if (nowVisible) {
8636 wtoken.appToken.windowsVisible();
8637 } else {
8638 wtoken.appToken.windowsGone();
8639 }
8640 } catch (RemoteException ex) {
8641 }
8642 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 case WINDOW_FREEZE_TIMEOUT: {
8645 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008646 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008647 int i = mWindows.size();
8648 while (i > 0) {
8649 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008650 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 if (w.mOrientationChanging) {
8652 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008653 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008654 }
8655 }
8656 performLayoutAndPlaceSurfacesLocked();
8657 }
8658 break;
8659 }
Romain Guy06882f82009-06-10 13:36:04 -07008660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008661 case HOLD_SCREEN_CHANGED: {
8662 Session oldHold;
8663 Session newHold;
8664 synchronized (mWindowMap) {
8665 oldHold = mLastReportedHold;
8666 newHold = (Session)msg.obj;
8667 mLastReportedHold = newHold;
8668 }
Romain Guy06882f82009-06-10 13:36:04 -07008669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 if (oldHold != newHold) {
8671 try {
8672 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008673 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 "window",
8675 BatteryStats.WAKE_TYPE_WINDOW);
8676 }
8677 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008678 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679 "window",
8680 BatteryStats.WAKE_TYPE_WINDOW);
8681 }
8682 } catch (RemoteException e) {
8683 }
8684 }
8685 break;
8686 }
Romain Guy06882f82009-06-10 13:36:04 -07008687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008688 case APP_TRANSITION_TIMEOUT: {
8689 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008690 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008691 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008692 "*** APP TRANSITION TIMEOUT");
8693 mAppTransitionReady = true;
8694 mAppTransitionTimeout = true;
8695 performLayoutAndPlaceSurfacesLocked();
8696 }
8697 }
8698 break;
8699 }
Romain Guy06882f82009-06-10 13:36:04 -07008700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008701 case PERSIST_ANIMATION_SCALE: {
8702 Settings.System.putFloat(mContext.getContentResolver(),
8703 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8704 Settings.System.putFloat(mContext.getContentResolver(),
8705 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8706 break;
8707 }
Romain Guy06882f82009-06-10 13:36:04 -07008708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 case FORCE_GC: {
8710 synchronized(mWindowMap) {
8711 if (mAnimationPending) {
8712 // If we are animating, don't do the gc now but
8713 // delay a bit so we don't interrupt the animation.
8714 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8715 2000);
8716 return;
8717 }
8718 // If we are currently rotating the display, it will
8719 // schedule a new message when done.
8720 if (mDisplayFrozen) {
8721 return;
8722 }
8723 mFreezeGcPending = 0;
8724 }
8725 Runtime.getRuntime().gc();
8726 break;
8727 }
Romain Guy06882f82009-06-10 13:36:04 -07008728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 case ENABLE_SCREEN: {
8730 performEnableScreen();
8731 break;
8732 }
Romain Guy06882f82009-06-10 13:36:04 -07008733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008734 case APP_FREEZE_TIMEOUT: {
8735 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008736 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008737 int i = mAppTokens.size();
8738 while (i > 0) {
8739 i--;
8740 AppWindowToken tok = mAppTokens.get(i);
8741 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008742 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008743 unsetAppFreezingScreenLocked(tok, true, true);
8744 }
8745 }
8746 }
8747 break;
8748 }
Romain Guy06882f82009-06-10 13:36:04 -07008749
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008750 case SEND_NEW_CONFIGURATION: {
8751 removeMessages(SEND_NEW_CONFIGURATION);
8752 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008753 break;
8754 }
Romain Guy06882f82009-06-10 13:36:04 -07008755
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008756 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008757 if (mWindowsChanged) {
8758 synchronized (mWindowMap) {
8759 mWindowsChanged = false;
8760 }
8761 notifyWindowsChanged();
8762 }
8763 break;
8764 }
8765
Christopher Tatea53146c2010-09-07 11:57:52 -07008766 case DRAG_START_TIMEOUT: {
8767 IBinder win = (IBinder)msg.obj;
8768 if (DEBUG_DRAG) {
8769 Slog.w(TAG, "Timeout starting drag by win " + win);
8770 }
8771 synchronized (mWindowMap) {
8772 // !!! TODO: ANR the app that has failed to start the drag in time
8773 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07008774 mDragState.unregister();
8775 mInputMonitor.updateInputWindowsLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07008776 mDragState.reset();
8777 mDragState = null;
8778 }
8779 }
Chris Tated4533f142010-10-19 15:15:08 -07008780 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07008781 }
8782
Chris Tated4533f142010-10-19 15:15:08 -07008783 case DRAG_END_TIMEOUT: {
8784 IBinder win = (IBinder)msg.obj;
8785 if (DEBUG_DRAG) {
8786 Slog.w(TAG, "Timeout ending drag to win " + win);
8787 }
8788 synchronized (mWindowMap) {
8789 // !!! TODO: ANR the drag-receiving app
8790 mDragState.mDragResult = false;
8791 mDragState.endDragLw();
8792 }
8793 break;
8794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 }
8796 }
8797 }
8798
8799 // -------------------------------------------------------------
8800 // IWindowManager API
8801 // -------------------------------------------------------------
8802
8803 public IWindowSession openSession(IInputMethodClient client,
8804 IInputContext inputContext) {
8805 if (client == null) throw new IllegalArgumentException("null client");
8806 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008807 Session session = new Session(client, inputContext);
8808 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008809 }
8810
8811 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8812 synchronized (mWindowMap) {
8813 // The focus for the client is the window immediately below
8814 // where we would place the input method window.
8815 int idx = findDesiredInputMethodWindowIndexLocked(false);
8816 WindowState imFocus;
8817 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008818 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008819 if (imFocus != null) {
8820 if (imFocus.mSession.mClient != null &&
8821 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8822 return true;
8823 }
8824 }
8825 }
8826 }
8827 return false;
8828 }
Romain Guy06882f82009-06-10 13:36:04 -07008829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008830 // -------------------------------------------------------------
8831 // Internals
8832 // -------------------------------------------------------------
8833
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008834 final WindowState windowForClientLocked(Session session, IWindow client,
8835 boolean throwOnError) {
8836 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008837 }
Romain Guy06882f82009-06-10 13:36:04 -07008838
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008839 final WindowState windowForClientLocked(Session session, IBinder client,
8840 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008842 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 TAG, "Looking up client " + client + ": " + win);
8844 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008845 RuntimeException ex = new IllegalArgumentException(
8846 "Requested window " + client + " does not exist");
8847 if (throwOnError) {
8848 throw ex;
8849 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008850 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008851 return null;
8852 }
8853 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008854 RuntimeException ex = new IllegalArgumentException(
8855 "Requested window " + client + " is in session " +
8856 win.mSession + ", not " + session);
8857 if (throwOnError) {
8858 throw ex;
8859 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008860 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008861 return null;
8862 }
8863
8864 return win;
8865 }
8866
Dianne Hackborna8f60182009-09-01 19:01:50 -07008867 final void rebuildAppWindowListLocked() {
8868 int NW = mWindows.size();
8869 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008870 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008871 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008872
Dianne Hackborna8f60182009-09-01 19:01:50 -07008873 // First remove all existing app windows.
8874 i=0;
8875 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07008876 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008877 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07008878 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008879 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008880 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008881 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008882 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008883 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008884 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008885 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8886 && lastWallpaper == i-1) {
8887 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008888 }
8889 i++;
8890 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008891
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008892 // The wallpaper window(s) typically live at the bottom of the stack,
8893 // so skip them before adding app tokens.
8894 lastWallpaper++;
8895 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008896
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008897 // First add all of the exiting app tokens... these are no longer
8898 // in the main app list, but still have windows shown. We put them
8899 // in the back because now that the animation is over we no longer
8900 // will care about them.
8901 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008902 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008903 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8904 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008905
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008906 // And add in the still active app tokens in Z order.
8907 NT = mAppTokens.size();
8908 for (int j=0; j<NT; j++) {
8909 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008910 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008911
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008912 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008913 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008914 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008915 + " windows but added " + i);
8916 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008917 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008919 private final void assignLayersLocked() {
8920 int N = mWindows.size();
8921 int curBaseLayer = 0;
8922 int curLayer = 0;
8923 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008925 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008926 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008927 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8928 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008929 curLayer += WINDOW_LAYER_MULTIPLIER;
8930 w.mLayer = curLayer;
8931 } else {
8932 curBaseLayer = curLayer = w.mBaseLayer;
8933 w.mLayer = curLayer;
8934 }
8935 if (w.mTargetAppToken != null) {
8936 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
8937 } else if (w.mAppToken != null) {
8938 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
8939 } else {
8940 w.mAnimLayer = w.mLayer;
8941 }
8942 if (w.mIsImWindow) {
8943 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008944 } else if (w.mIsWallpaper) {
8945 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008946 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008947 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008948 + w.mAnimLayer);
8949 //System.out.println(
8950 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8951 }
8952 }
8953
8954 private boolean mInLayout = false;
8955 private final void performLayoutAndPlaceSurfacesLocked() {
8956 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008957 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008958 throw new RuntimeException("Recursive call!");
8959 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008960 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008961 return;
8962 }
8963
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008964 if (mWaitingForConfig) {
8965 // Our configuration has changed (most likely rotation), but we
8966 // don't yet have the complete configuration to report to
8967 // applications. Don't do any window layout until we have it.
8968 return;
8969 }
8970
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008971 if (mDisplay == null) {
8972 // Not yet initialized, nothing to do.
8973 return;
8974 }
8975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008976 boolean recoveringMemory = false;
8977 if (mForceRemoves != null) {
8978 recoveringMemory = true;
8979 // Wait a little it for things to settle down, and off we go.
8980 for (int i=0; i<mForceRemoves.size(); i++) {
8981 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008982 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008983 removeWindowInnerLocked(ws.mSession, ws);
8984 }
8985 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008986 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008987 Object tmp = new Object();
8988 synchronized (tmp) {
8989 try {
8990 tmp.wait(250);
8991 } catch (InterruptedException e) {
8992 }
8993 }
8994 }
Romain Guy06882f82009-06-10 13:36:04 -07008995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008996 mInLayout = true;
8997 try {
8998 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07008999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000 int i = mPendingRemove.size()-1;
9001 if (i >= 0) {
9002 while (i >= 0) {
9003 WindowState w = mPendingRemove.get(i);
9004 removeWindowInnerLocked(w.mSession, w);
9005 i--;
9006 }
9007 mPendingRemove.clear();
9008
9009 mInLayout = false;
9010 assignLayersLocked();
9011 mLayoutNeeded = true;
9012 performLayoutAndPlaceSurfacesLocked();
9013
9014 } else {
9015 mInLayout = false;
9016 if (mLayoutNeeded) {
9017 requestAnimationLocked(0);
9018 }
9019 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009020 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009021 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9022 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 } catch (RuntimeException e) {
9025 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009026 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009027 }
9028 }
9029
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009030 private final int performLayoutLockedInner() {
9031 if (!mLayoutNeeded) {
9032 return 0;
9033 }
9034
9035 mLayoutNeeded = false;
9036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 final int dw = mDisplay.getWidth();
9038 final int dh = mDisplay.getHeight();
9039
9040 final int N = mWindows.size();
9041 int i;
9042
Joe Onorato8a9b2202010-02-26 18:56:32 -08009043 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009044 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9045
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009046 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009047
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009048 int seq = mLayoutSeq+1;
9049 if (seq < 0) seq = 0;
9050 mLayoutSeq = seq;
9051
9052 // First perform layout of any root windows (not attached
9053 // to another window).
9054 int topAttached = -1;
9055 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009056 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009057
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009058 // Don't do layout of a window if it is not visible, or
9059 // soon won't be visible, to avoid wasting time and funky
9060 // changes while a window is animating away.
9061 final AppWindowToken atoken = win.mAppToken;
9062 final boolean gone = win.mViewVisibility == View.GONE
9063 || !win.mRelayoutCalled
9064 || win.mRootToken.hidden
9065 || (atoken != null && atoken.hiddenRequested)
9066 || win.mAttachedHidden
9067 || win.mExiting || win.mDestroying;
9068
9069 if (!win.mLayoutAttached) {
9070 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
9071 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9072 + " mLayoutAttached=" + win.mLayoutAttached);
9073 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
9074 + win.mViewVisibility + " mRelayoutCalled="
9075 + win.mRelayoutCalled + " hidden="
9076 + win.mRootToken.hidden + " hiddenRequested="
9077 + (atoken != null && atoken.hiddenRequested)
9078 + " mAttachedHidden=" + win.mAttachedHidden);
9079 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009080
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009081 // If this view is GONE, then skip it -- keep the current
9082 // frame, and let the caller know so they can ignore it
9083 // if they want. (We do the normal layout for INVISIBLE
9084 // windows, since that means "perform layout as normal,
9085 // just don't display").
9086 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009087 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009088 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9089 win.mLayoutSeq = seq;
9090 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9091 + win.mFrame + " mContainingFrame="
9092 + win.mContainingFrame + " mDisplayFrame="
9093 + win.mDisplayFrame);
9094 } else {
9095 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009096 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009097 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009098 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009099
9100 // Now perform layout of attached windows, which usually
9101 // depend on the position of the window they are attached to.
9102 // XXX does not deal with windows that are attached to windows
9103 // that are themselves attached.
9104 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009105 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009106
9107 // If this view is GONE, then skip it -- keep the current
9108 // frame, and let the caller know so they can ignore it
9109 // if they want. (We do the normal layout for INVISIBLE
9110 // windows, since that means "perform layout as normal,
9111 // just don't display").
9112 if (win.mLayoutAttached) {
9113 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9114 + " mHaveFrame=" + win.mHaveFrame
9115 + " mViewVisibility=" + win.mViewVisibility
9116 + " mRelayoutCalled=" + win.mRelayoutCalled);
9117 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9118 || !win.mHaveFrame) {
9119 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9120 win.mLayoutSeq = seq;
9121 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9122 + win.mFrame + " mContainingFrame="
9123 + win.mContainingFrame + " mDisplayFrame="
9124 + win.mDisplayFrame);
9125 }
9126 }
9127 }
Jeff Brown349703e2010-06-22 01:27:15 -07009128
9129 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009130 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009131
9132 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009133 }
Romain Guy06882f82009-06-10 13:36:04 -07009134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009135 private final void performLayoutAndPlaceSurfacesLockedInner(
9136 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009137 if (mDisplay == null) {
9138 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9139 return;
9140 }
9141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 final long currentTime = SystemClock.uptimeMillis();
9143 final int dw = mDisplay.getWidth();
9144 final int dh = mDisplay.getHeight();
9145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 int i;
9147
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009148 if (mFocusMayChange) {
9149 mFocusMayChange = false;
9150 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9151 }
9152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009153 // Initialize state of exiting tokens.
9154 for (i=mExitingTokens.size()-1; i>=0; i--) {
9155 mExitingTokens.get(i).hasVisible = false;
9156 }
9157
9158 // Initialize state of exiting applications.
9159 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9160 mExitingAppTokens.get(i).hasVisible = false;
9161 }
9162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009163 boolean orientationChangeComplete = true;
9164 Session holdScreen = null;
9165 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009166 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009167 boolean focusDisplayed = false;
9168 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009169 boolean createWatermark = false;
9170
9171 if (mFxSession == null) {
9172 mFxSession = new SurfaceSession();
9173 createWatermark = true;
9174 }
9175
9176 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177
9178 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009179
9180 if (createWatermark) {
9181 createWatermark();
9182 }
9183 if (mWatermark != null) {
9184 mWatermark.positionSurface(dw, dh);
9185 }
9186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009188 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009189 int repeats = 0;
9190 int changes = 0;
9191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009192 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009193 repeats++;
9194 if (repeats > 6) {
9195 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9196 mLayoutNeeded = false;
9197 break;
9198 }
9199
9200 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9201 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9202 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9203 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9204 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9205 assignLayersLocked();
9206 mLayoutNeeded = true;
9207 }
9208 }
9209 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9210 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9211 if (updateOrientationFromAppTokensLocked()) {
9212 mLayoutNeeded = true;
9213 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9214 }
9215 }
9216 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9217 mLayoutNeeded = true;
9218 }
9219 }
9220
9221 // FIRST LOOP: Perform a layout, if needed.
9222 if (repeats < 4) {
9223 changes = performLayoutLockedInner();
9224 if (changes != 0) {
9225 continue;
9226 }
9227 } else {
9228 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9229 changes = 0;
9230 }
9231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009232 final int transactionSequence = ++mTransactionSequence;
9233
9234 // Update animations of all applications, including those
9235 // associated with exiting/removed apps
9236 boolean tokensAnimating = false;
9237 final int NAT = mAppTokens.size();
9238 for (i=0; i<NAT; i++) {
9239 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9240 tokensAnimating = true;
9241 }
9242 }
9243 final int NEAT = mExitingAppTokens.size();
9244 for (i=0; i<NEAT; i++) {
9245 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9246 tokensAnimating = true;
9247 }
9248 }
9249
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009250 // SECOND LOOP: Execute animations and update visibility of windows.
9251
Joe Onorato8a9b2202010-02-26 18:56:32 -08009252 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009253 + transactionSequence + " tokensAnimating="
9254 + tokensAnimating);
9255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009256 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009257
9258 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009259 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009260 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261
9262 mPolicy.beginAnimationLw(dw, dh);
9263
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009264 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009266 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009267 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268
9269 final WindowManager.LayoutParams attrs = w.mAttrs;
9270
9271 if (w.mSurface != null) {
9272 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009273 if (w.commitFinishDrawingLocked(currentTime)) {
9274 if ((w.mAttrs.flags
9275 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009276 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009277 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009278 wallpaperMayChange = true;
9279 }
9280 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009281
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009282 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283 if (w.stepAnimationLocked(currentTime, dw, dh)) {
9284 animating = true;
9285 //w.dump(" ");
9286 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009287 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9288 wallpaperMayChange = true;
9289 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009290
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009291 if (mPolicy.doesForceHide(w, attrs)) {
9292 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009293 if (DEBUG_VISIBILITY) Slog.v(TAG,
9294 "Animation done that could impact force hide: "
9295 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009296 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009297 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009298 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9299 forceHiding = true;
9300 }
9301 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9302 boolean changed;
9303 if (forceHiding) {
9304 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009305 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9306 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009307 } else {
9308 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009309 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9310 "Now policy shown: " + w);
9311 if (changed) {
9312 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009313 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009314 // Assume we will need to animate. If
9315 // we don't (because the wallpaper will
9316 // stay with the lock screen), then we will
9317 // clean up later.
9318 Animation a = mPolicy.createForceHideEnterAnimation();
9319 if (a != null) {
9320 w.setAnimation(a);
9321 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009322 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009323 if (mCurrentFocus == null ||
9324 mCurrentFocus.mLayer < w.mLayer) {
9325 // We are showing on to of the current
9326 // focus, so re-evaluate focus to make
9327 // sure it is correct.
9328 mFocusMayChange = true;
9329 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009330 }
9331 }
9332 if (changed && (attrs.flags
9333 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9334 wallpaperMayChange = true;
9335 }
9336 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009338 mPolicy.animatingWindowLw(w, attrs);
9339 }
9340
9341 final AppWindowToken atoken = w.mAppToken;
9342 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9343 if (atoken.lastTransactionSequence != transactionSequence) {
9344 atoken.lastTransactionSequence = transactionSequence;
9345 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9346 atoken.startingDisplayed = false;
9347 }
9348 if ((w.isOnScreen() || w.mAttrs.type
9349 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9350 && !w.mExiting && !w.mDestroying) {
9351 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009352 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009353 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009354 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009355 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009356 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 + " pv=" + w.mPolicyVisibility
9358 + " dp=" + w.mDrawPending
9359 + " cdp=" + w.mCommitDrawPending
9360 + " ah=" + w.mAttachedHidden
9361 + " th=" + atoken.hiddenRequested
9362 + " a=" + w.mAnimating);
9363 }
9364 }
9365 if (w != atoken.startingWindow) {
9366 if (!atoken.freezingScreen || !w.mAppFreezing) {
9367 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009368 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009370 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 "tokenMayBeDrawn: " + atoken
9372 + " freezingScreen=" + atoken.freezingScreen
9373 + " mAppFreezing=" + w.mAppFreezing);
9374 tokenMayBeDrawn = true;
9375 }
9376 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009377 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009378 atoken.startingDisplayed = true;
9379 }
9380 }
9381 } else if (w.mReadyToShow) {
9382 w.performShowLocked();
9383 }
9384 }
9385
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009386 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387
9388 if (tokenMayBeDrawn) {
9389 // See if any windows have been drawn, so they (and others
9390 // associated with them) can now be shown.
9391 final int NT = mTokenList.size();
9392 for (i=0; i<NT; i++) {
9393 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9394 if (wtoken == null) {
9395 continue;
9396 }
9397 if (wtoken.freezingScreen) {
9398 int numInteresting = wtoken.numInterestingWindows;
9399 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009400 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 "allDrawn: " + wtoken
9402 + " interesting=" + numInteresting
9403 + " drawn=" + wtoken.numDrawnWindows);
9404 wtoken.showAllWindowsLocked();
9405 unsetAppFreezingScreenLocked(wtoken, false, true);
9406 orientationChangeComplete = true;
9407 }
9408 } else if (!wtoken.allDrawn) {
9409 int numInteresting = wtoken.numInterestingWindows;
9410 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009411 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009412 "allDrawn: " + wtoken
9413 + " interesting=" + numInteresting
9414 + " drawn=" + wtoken.numDrawnWindows);
9415 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009416 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009417
9418 // We can now show all of the drawn windows!
9419 if (!mOpeningApps.contains(wtoken)) {
9420 wtoken.showAllWindowsLocked();
9421 }
9422 }
9423 }
9424 }
9425 }
9426
9427 // If we are ready to perform an app transition, check through
9428 // all of the app tokens to be shown and see if they are ready
9429 // to go.
9430 if (mAppTransitionReady) {
9431 int NN = mOpeningApps.size();
9432 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009433 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 "Checking " + NN + " opening apps (frozen="
9435 + mDisplayFrozen + " timeout="
9436 + mAppTransitionTimeout + ")...");
9437 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9438 // If the display isn't frozen, wait to do anything until
9439 // all of the apps are ready. Otherwise just go because
9440 // we'll unfreeze the display when everyone is ready.
9441 for (i=0; i<NN && goodToGo; i++) {
9442 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009443 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009444 "Check opening app" + wtoken + ": allDrawn="
9445 + wtoken.allDrawn + " startingDisplayed="
9446 + wtoken.startingDisplayed);
9447 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9448 && !wtoken.startingMoved) {
9449 goodToGo = false;
9450 }
9451 }
9452 }
9453 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009454 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009455 int transit = mNextAppTransition;
9456 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009457 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009458 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009459 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009460 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009461 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009462 mAppTransitionTimeout = false;
9463 mStartingIconInTransition = false;
9464 mSkipAppTransitionAnimation = false;
9465
9466 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9467
Dianne Hackborna8f60182009-09-01 19:01:50 -07009468 // If there are applications waiting to come to the
9469 // top of the stack, now is the time to move their windows.
9470 // (Note that we don't do apps going to the bottom
9471 // here -- we want to keep their windows in the old
9472 // Z-order until the animation completes.)
9473 if (mToTopApps.size() > 0) {
9474 NN = mAppTokens.size();
9475 for (i=0; i<NN; i++) {
9476 AppWindowToken wtoken = mAppTokens.get(i);
9477 if (wtoken.sendingToTop) {
9478 wtoken.sendingToTop = false;
9479 moveAppWindowsLocked(wtoken, NN, false);
9480 }
9481 }
9482 mToTopApps.clear();
9483 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009484
Dianne Hackborn25994b42009-09-04 14:21:19 -07009485 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009486
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009487 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009488 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009489
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009490 // The top-most window will supply the layout params,
9491 // and we will determine it below.
9492 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009493 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009494 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009495
Joe Onorato8a9b2202010-02-26 18:56:32 -08009496 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009497 "New wallpaper target=" + mWallpaperTarget
9498 + ", lower target=" + mLowerWallpaperTarget
9499 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009500 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009501 // Do a first pass through the tokens for two
9502 // things:
9503 // (1) Determine if both the closing and opening
9504 // app token sets are wallpaper targets, in which
9505 // case special animations are needed
9506 // (since the wallpaper needs to stay static
9507 // behind them).
9508 // (2) Find the layout params of the top-most
9509 // application window in the tokens, which is
9510 // what will control the animation theme.
9511 final int NC = mClosingApps.size();
9512 NN = NC + mOpeningApps.size();
9513 for (i=0; i<NN; i++) {
9514 AppWindowToken wtoken;
9515 int mode;
9516 if (i < NC) {
9517 wtoken = mClosingApps.get(i);
9518 mode = 1;
9519 } else {
9520 wtoken = mOpeningApps.get(i-NC);
9521 mode = 2;
9522 }
9523 if (mLowerWallpaperTarget != null) {
9524 if (mLowerWallpaperTarget.mAppToken == wtoken
9525 || mUpperWallpaperTarget.mAppToken == wtoken) {
9526 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009527 }
9528 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009529 if (wtoken.appFullscreen) {
9530 WindowState ws = wtoken.findMainWindow();
9531 if (ws != null) {
9532 // If this is a compatibility mode
9533 // window, we will always use its anim.
9534 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9535 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009536 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009537 bestAnimLayer = Integer.MAX_VALUE;
9538 } else if (ws.mLayer > bestAnimLayer) {
9539 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009540 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009541 bestAnimLayer = ws.mLayer;
9542 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009543 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009544 }
9545 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009546
Dianne Hackborn25994b42009-09-04 14:21:19 -07009547 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009548 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009549 "Wallpaper animation!");
9550 switch (transit) {
9551 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9552 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9553 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9554 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9555 break;
9556 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9557 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9558 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9559 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9560 break;
9561 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009562 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009563 "New transit: " + transit);
9564 } else if (oldWallpaper != null) {
9565 // We are transitioning from an activity with
9566 // a wallpaper to one without.
9567 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009568 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009569 "New transit away from wallpaper: " + transit);
9570 } else if (mWallpaperTarget != null) {
9571 // We are transitioning from an activity without
9572 // a wallpaper to now showing the wallpaper
9573 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009574 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009575 "New transit into wallpaper: " + transit);
9576 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009577
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009578 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9579 mLastEnterAnimToken = animToken;
9580 mLastEnterAnimParams = animLp;
9581 } else if (mLastEnterAnimParams != null) {
9582 animLp = mLastEnterAnimParams;
9583 mLastEnterAnimToken = null;
9584 mLastEnterAnimParams = null;
9585 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009586
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009587 // If all closing windows are obscured, then there is
9588 // no need to do an animation. This is the case, for
9589 // example, when this transition is being done behind
9590 // the lock screen.
9591 if (!mPolicy.allowAppAnimationsLw()) {
9592 animLp = null;
9593 }
9594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009595 NN = mOpeningApps.size();
9596 for (i=0; i<NN; i++) {
9597 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009598 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 "Now opening app" + wtoken);
9600 wtoken.reportedVisible = false;
9601 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009602 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009603 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009605 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 wtoken.showAllWindowsLocked();
9607 }
9608 NN = mClosingApps.size();
9609 for (i=0; i<NN; i++) {
9610 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009611 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009612 "Now closing app" + wtoken);
9613 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009614 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009615 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009617 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 // Force the allDrawn flag, because we want to start
9619 // this guy's animations regardless of whether it's
9620 // gotten drawn.
9621 wtoken.allDrawn = true;
9622 }
9623
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009624 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009626 mOpeningApps.clear();
9627 mClosingApps.clear();
9628
9629 // This has changed the visibility of windows, so perform
9630 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009631 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009633 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9634 assignLayersLocked();
9635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009636 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009637 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009638 }
9639 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009640
Dianne Hackborn16064f92010-03-25 00:47:24 -07009641 int adjResult = 0;
9642
Dianne Hackborna8f60182009-09-01 19:01:50 -07009643 if (!animating && mAppTransitionRunning) {
9644 // We have finished the animation of an app transition. To do
9645 // this, we have delayed a lot of operations like showing and
9646 // hiding apps, moving apps in Z-order, etc. The app token list
9647 // reflects the correct Z-order, but the window list may now
9648 // be out of sync with it. So here we will just rebuild the
9649 // entire app window list. Fun!
9650 mAppTransitionRunning = false;
9651 // Clear information about apps that were moving.
9652 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009653
Dianne Hackborna8f60182009-09-01 19:01:50 -07009654 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009655 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009656 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009657 moveInputMethodWindowsIfNeededLocked(false);
9658 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009659 // Since the window list has been rebuilt, focus might
9660 // have to be recomputed since the actual order of windows
9661 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009662 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009663 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009664
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009665 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009666 // At this point, there was a window with a wallpaper that
9667 // was force hiding other windows behind it, but now it
9668 // is going away. This may be simple -- just animate
9669 // away the wallpaper and its window -- or it may be
9670 // hard -- the wallpaper now needs to be shown behind
9671 // something that was hidden.
9672 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009673 if (mLowerWallpaperTarget != null
9674 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009675 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009676 "wallpaperForceHiding changed with lower="
9677 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009678 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009679 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
9680 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
9681 if (mLowerWallpaperTarget.mAppToken.hidden) {
9682 // The lower target has become hidden before we
9683 // actually started the animation... let's completely
9684 // re-evaluate everything.
9685 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009686 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009687 }
9688 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07009689 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009690 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009691 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009692 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009693 + " NEW: " + mWallpaperTarget
9694 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009695 if (mLowerWallpaperTarget == null) {
9696 // Whoops, we don't need a special wallpaper animation.
9697 // Clear them out.
9698 forceHiding = false;
9699 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009700 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009701 if (w.mSurface != null) {
9702 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07009703 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009704 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009705 forceHiding = true;
9706 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9707 if (!w.mAnimating) {
9708 // We set the animation above so it
9709 // is not yet running.
9710 w.clearAnimation();
9711 }
9712 }
9713 }
9714 }
9715 }
9716 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009717
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009718 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009719 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009720 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07009721 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009722 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009723
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009724 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009725 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009726 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009727 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009728 assignLayersLocked();
9729 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009730 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009731 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009732 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009733 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009734
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009735 if (mFocusMayChange) {
9736 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009737 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009738 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009739 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009740 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009741 }
9742
9743 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009744 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009745 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009746
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009747 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
9748 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009749
Jeff Browne33348b2010-07-15 23:54:05 -07009750 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009751 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752
9753 // THIRD LOOP: Update the surfaces of all windows.
9754
9755 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9756
9757 boolean obscured = false;
9758 boolean blurring = false;
9759 boolean dimming = false;
9760 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009761 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009762 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009763
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009764 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009767 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009768
9769 boolean displayed = false;
9770 final WindowManager.LayoutParams attrs = w.mAttrs;
9771 final int attrFlags = attrs.flags;
9772
9773 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009774 // XXX NOTE: The logic here could be improved. We have
9775 // the decision about whether to resize a window separated
9776 // from whether to hide the surface. This can cause us to
9777 // resize a surface even if we are going to hide it. You
9778 // can see this by (1) holding device in landscape mode on
9779 // home screen; (2) tapping browser icon (device will rotate
9780 // to landscape; (3) tap home. The wallpaper will be resized
9781 // in step 2 but then immediately hidden, causing us to
9782 // have to resize and then redraw it again in step 3. It
9783 // would be nice to figure out how to avoid this, but it is
9784 // difficult because we do need to resize surfaces in some
9785 // cases while they are hidden such as when first showing a
9786 // window.
9787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009789 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009790 TAG, "Placing surface #" + i + " " + w.mSurface
9791 + ": new=" + w.mShownFrame + ", old="
9792 + w.mLastShownFrame);
9793
9794 boolean resize;
9795 int width, height;
9796 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9797 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9798 w.mLastRequestedHeight != w.mRequestedHeight;
9799 // for a scaled surface, we just want to use
9800 // the requested size.
9801 width = w.mRequestedWidth;
9802 height = w.mRequestedHeight;
9803 w.mLastRequestedWidth = width;
9804 w.mLastRequestedHeight = height;
9805 w.mLastShownFrame.set(w.mShownFrame);
9806 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009807 if (SHOW_TRANSACTIONS) logSurface(w,
9808 "POS " + w.mShownFrame.left
9809 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009810 w.mSurfaceX = w.mShownFrame.left;
9811 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9813 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009814 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 if (!recoveringMemory) {
9816 reclaimSomeSurfaceMemoryLocked(w, "position");
9817 }
9818 }
9819 } else {
9820 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9821 width = w.mShownFrame.width();
9822 height = w.mShownFrame.height();
9823 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009824 }
9825
9826 if (resize) {
9827 if (width < 1) width = 1;
9828 if (height < 1) height = 1;
9829 if (w.mSurface != null) {
9830 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009831 if (SHOW_TRANSACTIONS) logSurface(w,
9832 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009833 + w.mShownFrame.top + " SIZE "
9834 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009835 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009836 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009837 w.mSurfaceW = width;
9838 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009839 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009840 w.mSurfaceX = w.mShownFrame.left;
9841 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 w.mSurface.setPosition(w.mShownFrame.left,
9843 w.mShownFrame.top);
9844 } catch (RuntimeException e) {
9845 // If something goes wrong with the surface (such
9846 // as running out of memory), don't take down the
9847 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009848 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849 + "size=(" + width + "x" + height
9850 + "), pos=(" + w.mShownFrame.left
9851 + "," + w.mShownFrame.top + ")", e);
9852 if (!recoveringMemory) {
9853 reclaimSomeSurfaceMemoryLocked(w, "size");
9854 }
9855 }
9856 }
9857 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009858 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 w.mContentInsetsChanged =
9860 !w.mLastContentInsets.equals(w.mContentInsets);
9861 w.mVisibleInsetsChanged =
9862 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009863 boolean configChanged =
9864 w.mConfiguration != mCurConfiguration
9865 && (w.mConfiguration == null
9866 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009867 if (DEBUG_CONFIGURATION && configChanged) {
9868 Slog.v(TAG, "Win " + w + " config changed: "
9869 + mCurConfiguration);
9870 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009871 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009872 + ": configChanged=" + configChanged
9873 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -07009874 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009875 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009876 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009877 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009878 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 w.mLastFrame.set(w.mFrame);
9880 w.mLastContentInsets.set(w.mContentInsets);
9881 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009882 // If the screen is currently frozen, then keep
9883 // it frozen until this window draws at its new
9884 // orientation.
9885 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009886 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009887 "Resizing while display frozen: " + w);
9888 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009889 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009890 mWindowsFreezingScreen = true;
9891 // XXX should probably keep timeout from
9892 // when we first froze the display.
9893 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9894 mH.sendMessageDelayed(mH.obtainMessage(
9895 H.WINDOW_FREEZE_TIMEOUT), 2000);
9896 }
9897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 // If the orientation is changing, then we need to
9899 // hold off on unfreezing the display until this
9900 // window has been redrawn; to do that, we need
9901 // to go through the process of getting informed
9902 // by the application when it has finished drawing.
9903 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009904 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 "Orientation start waiting for draw in "
9906 + w + ", surface " + w.mSurface);
9907 w.mDrawPending = true;
9908 w.mCommitDrawPending = false;
9909 w.mReadyToShow = false;
9910 if (w.mAppToken != null) {
9911 w.mAppToken.allDrawn = false;
9912 }
9913 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009914 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 "Resizing window " + w + " to " + w.mFrame);
9916 mResizingWindows.add(w);
9917 } else if (w.mOrientationChanging) {
9918 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009919 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009920 "Orientation not waiting for draw in "
9921 + w + ", surface " + w.mSurface);
9922 w.mOrientationChanging = false;
9923 }
9924 }
9925 }
9926
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009927 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009928 if (!w.mLastHidden) {
9929 //dump();
9930 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009931 if (SHOW_TRANSACTIONS) logSurface(w,
9932 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009934 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009935 try {
9936 w.mSurface.hide();
9937 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009938 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 }
9940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009941 }
9942 // If we are waiting for this window to handle an
9943 // orientation change, well, it is hidden, so
9944 // doesn't really matter. Note that this does
9945 // introduce a potential glitch if the window
9946 // becomes unhidden before it has drawn for the
9947 // new orientation.
9948 if (w.mOrientationChanging) {
9949 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009950 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 "Orientation change skips hidden " + w);
9952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 } else if (w.mLastLayer != w.mAnimLayer
9954 || w.mLastAlpha != w.mShownAlpha
9955 || w.mLastDsDx != w.mDsDx
9956 || w.mLastDtDx != w.mDtDx
9957 || w.mLastDsDy != w.mDsDy
9958 || w.mLastDtDy != w.mDtDy
9959 || w.mLastHScale != w.mHScale
9960 || w.mLastVScale != w.mVScale
9961 || w.mLastHidden) {
9962 displayed = true;
9963 w.mLastAlpha = w.mShownAlpha;
9964 w.mLastLayer = w.mAnimLayer;
9965 w.mLastDsDx = w.mDsDx;
9966 w.mLastDtDx = w.mDtDx;
9967 w.mLastDsDy = w.mDsDy;
9968 w.mLastDtDy = w.mDtDy;
9969 w.mLastHScale = w.mHScale;
9970 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009971 if (SHOW_TRANSACTIONS) logSurface(w,
9972 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009973 + " matrix=[" + (w.mDsDx*w.mHScale)
9974 + "," + (w.mDtDx*w.mVScale)
9975 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009976 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009977 if (w.mSurface != null) {
9978 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009979 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009980 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009981 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009982 w.mSurface.setLayer(w.mAnimLayer);
9983 w.mSurface.setMatrix(
9984 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
9985 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
9986 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009987 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 if (!recoveringMemory) {
9989 reclaimSomeSurfaceMemoryLocked(w, "update");
9990 }
9991 }
9992 }
9993
9994 if (w.mLastHidden && !w.mDrawPending
9995 && !w.mCommitDrawPending
9996 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009997 if (SHOW_TRANSACTIONS) logSurface(w,
9998 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009999 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 + " during relayout");
10001 if (showSurfaceRobustlyLocked(w)) {
10002 w.mHasDrawn = true;
10003 w.mLastHidden = false;
10004 } else {
10005 w.mOrientationChanging = false;
10006 }
10007 }
10008 if (w.mSurface != null) {
10009 w.mToken.hasVisible = true;
10010 }
10011 } else {
10012 displayed = true;
10013 }
10014
10015 if (displayed) {
10016 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010017 if (attrs.width == LayoutParams.MATCH_PARENT
10018 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019 covered = true;
10020 }
10021 }
10022 if (w.mOrientationChanging) {
10023 if (w.mDrawPending || w.mCommitDrawPending) {
10024 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010025 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 "Orientation continue waiting for draw in " + w);
10027 } else {
10028 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010029 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010030 "Orientation change complete in " + w);
10031 }
10032 }
10033 w.mToken.hasVisible = true;
10034 }
10035 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010036 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 "Orientation change skips hidden " + w);
10038 w.mOrientationChanging = false;
10039 }
10040
10041 final boolean canBeSeen = w.isDisplayedLw();
10042
10043 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10044 focusDisplayed = true;
10045 }
10046
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010047 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010050 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 if (w.mSurface != null) {
10052 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10053 holdScreen = w.mSession;
10054 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010055 if (!syswin && w.mAttrs.screenBrightness >= 0
10056 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057 screenBrightness = w.mAttrs.screenBrightness;
10058 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010059 if (!syswin && w.mAttrs.buttonBrightness >= 0
10060 && buttonBrightness < 0) {
10061 buttonBrightness = w.mAttrs.buttonBrightness;
10062 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010063 if (canBeSeen
10064 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10065 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10066 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010067 syswin = true;
10068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010069 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010070
Dianne Hackborn25994b42009-09-04 14:21:19 -070010071 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10072 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 // This window completely covers everything behind it,
10074 // so we want to leave all of them as unblurred (for
10075 // performance reasons).
10076 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010077 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010078 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010079 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010080 obscured = true;
10081 if (mBackgroundFillerSurface == null) {
10082 try {
10083 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010084 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010085 0, dw, dh,
10086 PixelFormat.OPAQUE,
10087 Surface.FX_SURFACE_NORMAL);
10088 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010089 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010090 }
10091 }
10092 try {
10093 mBackgroundFillerSurface.setPosition(0, 0);
10094 mBackgroundFillerSurface.setSize(dw, dh);
10095 // Using the same layer as Dim because they will never be shown at the
10096 // same time.
10097 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10098 mBackgroundFillerSurface.show();
10099 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010100 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010101 }
10102 backgroundFillerShown = true;
10103 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010104 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010106 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 + ": blurring=" + blurring
10108 + " obscured=" + obscured
10109 + " displayed=" + displayed);
10110 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10111 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010112 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010114 if (mDimAnimator == null) {
10115 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010116 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010117 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010118 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120 }
10121 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10122 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010123 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010126 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 + mBlurSurface + ": CREATE");
10128 try {
Romain Guy06882f82009-06-10 13:36:04 -070010129 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010130 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010131 -1, 16, 16,
10132 PixelFormat.OPAQUE,
10133 Surface.FX_SURFACE_BLUR);
10134 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010135 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010136 }
10137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010138 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010139 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10140 + mBlurSurface + ": pos=(0,0) (" +
10141 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010142 mBlurSurface.setPosition(0, 0);
10143 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010144 mBlurSurface.setLayer(w.mAnimLayer-2);
10145 if (!mBlurShown) {
10146 try {
10147 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10148 + mBlurSurface + ": SHOW");
10149 mBlurSurface.show();
10150 } catch (RuntimeException e) {
10151 Slog.w(TAG, "Failure showing blur surface", e);
10152 }
10153 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 }
10155 }
10156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010157 }
10158 }
10159 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010160
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010161 if (obscuredChanged && mWallpaperTarget == w) {
10162 // This is the wallpaper target and its obscured state
10163 // changed... make sure the current wallaper's visibility
10164 // has been updated accordingly.
10165 updateWallpaperVisibilityLocked();
10166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010168
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010169 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10170 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010171 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010172 try {
10173 mBackgroundFillerSurface.hide();
10174 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010175 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010176 }
10177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010178
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010179 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010180 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10181 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 }
Romain Guy06882f82009-06-10 13:36:04 -070010183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010185 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010186 + ": HIDE");
10187 try {
10188 mBlurSurface.hide();
10189 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010190 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010191 }
10192 mBlurShown = false;
10193 }
10194
Joe Onorato8a9b2202010-02-26 18:56:32 -080010195 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010197 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010198 }
10199
Jeff Browne33348b2010-07-15 23:54:05 -070010200 mInputMonitor.updateInputWindowsLw();
10201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010203
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010204 if (mWatermark != null) {
10205 mWatermark.drawIfNeeded();
10206 }
10207
Joe Onorato8a9b2202010-02-26 18:56:32 -080010208 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 "With display frozen, orientationChangeComplete="
10210 + orientationChangeComplete);
10211 if (orientationChangeComplete) {
10212 if (mWindowsFreezingScreen) {
10213 mWindowsFreezingScreen = false;
10214 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10215 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010216 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010217 }
Romain Guy06882f82009-06-10 13:36:04 -070010218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 i = mResizingWindows.size();
10220 if (i > 0) {
10221 do {
10222 i--;
10223 WindowState win = mResizingWindows.get(i);
10224 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010225 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10226 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010227 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010228 boolean configChanged =
10229 win.mConfiguration != mCurConfiguration
10230 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010231 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10232 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10233 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010234 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010235 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010236 + " / " + mCurConfiguration + " / 0x"
10237 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010238 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010239 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010240 win.mClient.resized(win.mFrame.width(),
10241 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010242 win.mLastVisibleInsets, win.mDrawPending,
10243 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 win.mContentInsetsChanged = false;
10245 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010246 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 } catch (RemoteException e) {
10248 win.mOrientationChanging = false;
10249 }
10250 } while (i > 0);
10251 mResizingWindows.clear();
10252 }
Romain Guy06882f82009-06-10 13:36:04 -070010253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010255 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010256 i = mDestroySurface.size();
10257 if (i > 0) {
10258 do {
10259 i--;
10260 WindowState win = mDestroySurface.get(i);
10261 win.mDestroying = false;
10262 if (mInputMethodWindow == win) {
10263 mInputMethodWindow = null;
10264 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010265 if (win == mWallpaperTarget) {
10266 wallpaperDestroyed = true;
10267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 win.destroySurfaceLocked();
10269 } while (i > 0);
10270 mDestroySurface.clear();
10271 }
10272
10273 // Time to remove any exiting tokens?
10274 for (i=mExitingTokens.size()-1; i>=0; i--) {
10275 WindowToken token = mExitingTokens.get(i);
10276 if (!token.hasVisible) {
10277 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010278 if (token.windowType == TYPE_WALLPAPER) {
10279 mWallpaperTokens.remove(token);
10280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 }
10282 }
10283
10284 // Time to remove any exiting applications?
10285 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10286 AppWindowToken token = mExitingAppTokens.get(i);
10287 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010288 // Make sure there is no animation running on this token,
10289 // so any windows associated with it will be removed as
10290 // soon as their animations are complete
10291 token.animation = null;
10292 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 mAppTokens.remove(token);
10294 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010295 if (mLastEnterAnimToken == token) {
10296 mLastEnterAnimToken = null;
10297 mLastEnterAnimParams = null;
10298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 }
10300 }
10301
Dianne Hackborna8f60182009-09-01 19:01:50 -070010302 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010303
Dianne Hackborna8f60182009-09-01 19:01:50 -070010304 if (!animating && mAppTransitionRunning) {
10305 // We have finished the animation of an app transition. To do
10306 // this, we have delayed a lot of operations like showing and
10307 // hiding apps, moving apps in Z-order, etc. The app token list
10308 // reflects the correct Z-order, but the window list may now
10309 // be out of sync with it. So here we will just rebuild the
10310 // entire app window list. Fun!
10311 mAppTransitionRunning = false;
10312 needRelayout = true;
10313 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010314 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010315 // Clear information about apps that were moving.
10316 mToBottomApps.clear();
10317 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 if (focusDisplayed) {
10320 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10321 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010322 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010323 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010324 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010325 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010326 requestAnimationLocked(0);
10327 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10329 }
Jeff Browneb857f12010-07-16 10:06:33 -070010330
Jeff Browne33348b2010-07-15 23:54:05 -070010331 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010332
Jeff Brown8e03b752010-06-13 19:16:55 -070010333 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10335 mPowerManager.setScreenBrightnessOverride(-1);
10336 } else {
10337 mPowerManager.setScreenBrightnessOverride((int)
10338 (screenBrightness * Power.BRIGHTNESS_ON));
10339 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010340 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10341 mPowerManager.setButtonBrightnessOverride(-1);
10342 } else {
10343 mPowerManager.setButtonBrightnessOverride((int)
10344 (buttonBrightness * Power.BRIGHTNESS_ON));
10345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 if (holdScreen != mHoldingScreenOn) {
10347 mHoldingScreenOn = holdScreen;
10348 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10349 mH.sendMessage(m);
10350 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010351
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010352 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010353 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010354 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10355 LocalPowerManager.BUTTON_EVENT, true);
10356 mTurnOnScreen = false;
10357 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010358
10359 // Check to see if we are now in a state where the screen should
10360 // be enabled, because the window obscured flags have changed.
10361 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010362 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010363
10364 /**
10365 * Must be called with the main window manager lock held.
10366 */
10367 void setHoldScreenLocked(boolean holding) {
10368 boolean state = mHoldingScreenWakeLock.isHeld();
10369 if (holding != state) {
10370 if (holding) {
10371 mHoldingScreenWakeLock.acquire();
10372 } else {
10373 mPolicy.screenOnStoppedLw();
10374 mHoldingScreenWakeLock.release();
10375 }
10376 }
10377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378
10379 void requestAnimationLocked(long delay) {
10380 if (!mAnimationPending) {
10381 mAnimationPending = true;
10382 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10383 }
10384 }
Romain Guy06882f82009-06-10 13:36:04 -070010385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010386 /**
10387 * Have the surface flinger show a surface, robustly dealing with
10388 * error conditions. In particular, if there is not enough memory
10389 * to show the surface, then we will try to get rid of other surfaces
10390 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010391 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 * @return Returns true if the surface was successfully shown.
10393 */
10394 boolean showSurfaceRobustlyLocked(WindowState win) {
10395 try {
10396 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010397 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010398 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010399 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010400 if (DEBUG_VISIBILITY) Slog.v(TAG,
10401 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010402 win.mTurnOnScreen = false;
10403 mTurnOnScreen = true;
10404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 }
10406 return true;
10407 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010408 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010409 }
Romain Guy06882f82009-06-10 13:36:04 -070010410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413 return false;
10414 }
Romain Guy06882f82009-06-10 13:36:04 -070010415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010416 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10417 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010418
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010419 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010422 if (mForceRemoves == null) {
10423 mForceRemoves = new ArrayList<WindowState>();
10424 }
Romain Guy06882f82009-06-10 13:36:04 -070010425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010426 long callingIdentity = Binder.clearCallingIdentity();
10427 try {
10428 // There was some problem... first, do a sanity check of the
10429 // window list to make sure we haven't left any dangling surfaces
10430 // around.
10431 int N = mWindows.size();
10432 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010433 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010435 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 if (ws.mSurface != null) {
10437 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010438 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 + ws + " surface=" + ws.mSurface
10440 + " token=" + win.mToken
10441 + " pid=" + ws.mSession.mPid
10442 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010443 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010444 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 ws.mSurface = null;
10446 mForceRemoves.add(ws);
10447 i--;
10448 N--;
10449 leakedSurface = true;
10450 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 + ws + " surface=" + ws.mSurface
10453 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010454 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010455 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010456 ws.mSurface = null;
10457 leakedSurface = true;
10458 }
10459 }
10460 }
Romain Guy06882f82009-06-10 13:36:04 -070010461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 boolean killedApps = false;
10463 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010464 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010465 SparseIntArray pidCandidates = new SparseIntArray();
10466 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010467 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010468 if (ws.mSurface != null) {
10469 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10470 }
10471 }
10472 if (pidCandidates.size() > 0) {
10473 int[] pids = new int[pidCandidates.size()];
10474 for (int i=0; i<pids.length; i++) {
10475 pids[i] = pidCandidates.keyAt(i);
10476 }
10477 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010478 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010479 killedApps = true;
10480 }
10481 } catch (RemoteException e) {
10482 }
10483 }
10484 }
Romain Guy06882f82009-06-10 13:36:04 -070010485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486 if (leakedSurface || killedApps) {
10487 // We managed to reclaim some memory, so get rid of the trouble
10488 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010489 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010491 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010492 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010493 win.mSurface = null;
10494 }
Romain Guy06882f82009-06-10 13:36:04 -070010495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010496 try {
10497 win.mClient.dispatchGetNewSurface();
10498 } catch (RemoteException e) {
10499 }
10500 }
10501 } finally {
10502 Binder.restoreCallingIdentity(callingIdentity);
10503 }
10504 }
Romain Guy06882f82009-06-10 13:36:04 -070010505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010506 private boolean updateFocusedWindowLocked(int mode) {
10507 WindowState newFocus = computeFocusedWindowLocked();
10508 if (mCurrentFocus != newFocus) {
10509 // This check makes sure that we don't already have the focus
10510 // change message pending.
10511 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10512 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010513 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010514 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10515 final WindowState oldFocus = mCurrentFocus;
10516 mCurrentFocus = newFocus;
10517 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010519 final WindowState imWindow = mInputMethodWindow;
10520 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010521 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010523 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10524 mLayoutNeeded = true;
10525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010526 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
10527 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010528 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10529 // Client will do the layout, but we need to assign layers
10530 // for handleNewWindowLocked() below.
10531 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010532 }
10533 }
Jeff Brown349703e2010-06-22 01:27:15 -070010534
10535 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10536 // If we defer assigning layers, then the caller is responsible for
10537 // doing this part.
10538 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 return true;
10541 }
10542 return false;
10543 }
Jeff Brown349703e2010-06-22 01:27:15 -070010544
10545 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010546 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548
10549 private WindowState computeFocusedWindowLocked() {
10550 WindowState result = null;
10551 WindowState win;
10552
10553 int i = mWindows.size() - 1;
10554 int nextAppIndex = mAppTokens.size()-1;
10555 WindowToken nextApp = nextAppIndex >= 0
10556 ? mAppTokens.get(nextAppIndex) : null;
10557
10558 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010559 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010560
Joe Onorato8a9b2202010-02-26 18:56:32 -080010561 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010562 TAG, "Looking for focus: " + i
10563 + " = " + win
10564 + ", flags=" + win.mAttrs.flags
10565 + ", canReceive=" + win.canReceiveKeys());
10566
10567 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010569 // If this window's application has been removed, just skip it.
10570 if (thisApp != null && thisApp.removed) {
10571 i--;
10572 continue;
10573 }
Romain Guy06882f82009-06-10 13:36:04 -070010574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010575 // If there is a focused app, don't allow focus to go to any
10576 // windows below it. If this is an application window, step
10577 // through the app tokens until we find its app.
10578 if (thisApp != null && nextApp != null && thisApp != nextApp
10579 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10580 int origAppIndex = nextAppIndex;
10581 while (nextAppIndex > 0) {
10582 if (nextApp == mFocusedApp) {
10583 // Whoops, we are below the focused app... no focus
10584 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010585 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 TAG, "Reached focused app: " + mFocusedApp);
10587 return null;
10588 }
10589 nextAppIndex--;
10590 nextApp = mAppTokens.get(nextAppIndex);
10591 if (nextApp == thisApp) {
10592 break;
10593 }
10594 }
10595 if (thisApp != nextApp) {
10596 // Uh oh, the app token doesn't exist! This shouldn't
10597 // happen, but if it does we can get totally hosed...
10598 // so restart at the original app.
10599 nextAppIndex = origAppIndex;
10600 nextApp = mAppTokens.get(nextAppIndex);
10601 }
10602 }
10603
10604 // Dispatch to this window if it is wants key events.
10605 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010606 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 TAG, "Found focus @ " + i + " = " + win);
10608 result = win;
10609 break;
10610 }
10611
10612 i--;
10613 }
10614
10615 return result;
10616 }
10617
10618 private void startFreezingDisplayLocked() {
10619 if (mDisplayFrozen) {
10620 return;
10621 }
Romain Guy06882f82009-06-10 13:36:04 -070010622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010623 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010625 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010626 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010627 if (mFreezeGcPending != 0) {
10628 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010629 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010630 mH.removeMessages(H.FORCE_GC);
10631 Runtime.getRuntime().gc();
10632 mFreezeGcPending = now;
10633 }
10634 } else {
10635 mFreezeGcPending = now;
10636 }
Romain Guy06882f82009-06-10 13:36:04 -070010637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010638 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010639
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010640 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010641
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010642 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10643 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010644 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010645 mAppTransitionReady = true;
10646 }
Romain Guy06882f82009-06-10 13:36:04 -070010647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010648 if (PROFILE_ORIENTATION) {
10649 File file = new File("/data/system/frozen");
10650 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10651 }
10652 Surface.freezeDisplay(0);
10653 }
Romain Guy06882f82009-06-10 13:36:04 -070010654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010655 private void stopFreezingDisplayLocked() {
10656 if (!mDisplayFrozen) {
10657 return;
10658 }
Romain Guy06882f82009-06-10 13:36:04 -070010659
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010660 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
10661 return;
10662 }
10663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 mDisplayFrozen = false;
10665 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
10666 if (PROFILE_ORIENTATION) {
10667 Debug.stopMethodTracing();
10668 }
10669 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070010670
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010671 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672
Christopher Tateb696aee2010-04-02 19:08:30 -070010673 // While the display is frozen we don't re-compute the orientation
10674 // to avoid inconsistent states. However, something interesting
10675 // could have actually changed during that time so re-evaluate it
10676 // now to catch that.
10677 if (updateOrientationFromAppTokensLocked()) {
10678 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10679 }
10680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 // A little kludge: a lot could have happened while the
10682 // display was frozen, so now that we are coming back we
10683 // do a gc so that any remote references the system
10684 // processes holds on others can be released if they are
10685 // no longer needed.
10686 mH.removeMessages(H.FORCE_GC);
10687 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10688 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010690 mScreenFrozenLock.release();
10691 }
Romain Guy06882f82009-06-10 13:36:04 -070010692
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010693 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10694 DisplayMetrics dm) {
10695 if (index < tokens.length) {
10696 String str = tokens[index];
10697 if (str != null && str.length() > 0) {
10698 try {
10699 int val = Integer.parseInt(str);
10700 return val;
10701 } catch (Exception e) {
10702 }
10703 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010704 }
10705 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10706 return defDps;
10707 }
10708 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10709 return val;
10710 }
10711
10712 class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010713 final String[] mTokens;
10714 final String mText;
10715 final Paint mTextPaint;
10716 final int mTextWidth;
10717 final int mTextHeight;
10718 final int mTextAscent;
10719 final int mTextDescent;
10720 final int mDeltaX;
10721 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010722
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010723 Surface mSurface;
10724 int mLastDW;
10725 int mLastDH;
10726 boolean mDrawNeeded;
10727
10728 Watermark(SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010729 final DisplayMetrics dm = new DisplayMetrics();
10730 mDisplay.getMetrics(dm);
10731
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010732 if (false) {
10733 Log.i(TAG, "*********************** WATERMARK");
10734 for (int i=0; i<tokens.length; i++) {
10735 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
10736 }
10737 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010738
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010739 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010740
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010741 StringBuilder builder = new StringBuilder(32);
10742 int len = mTokens[0].length();
10743 len = len & ~1;
10744 for (int i=0; i<len; i+=2) {
10745 int c1 = mTokens[0].charAt(i);
10746 int c2 = mTokens[0].charAt(i+1);
10747 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
10748 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
10749 else c1 -= '0';
10750 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
10751 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
10752 else c2 -= '0';
10753 builder.append((char)(255-((c1*16)+c2)));
10754 }
10755 mText = builder.toString();
10756 if (false) {
10757 Log.i(TAG, "Final text: " + mText);
10758 }
10759
10760 int fontSize = getPropertyInt(tokens, 1,
10761 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
10762
10763 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
10764 mTextPaint.setTextSize(fontSize);
10765 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
10766
10767 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
10768 mTextWidth = (int)mTextPaint.measureText(mText);
10769 mTextAscent = fm.ascent;
10770 mTextDescent = fm.descent;
10771 mTextHeight = fm.descent - fm.ascent;
10772
10773 mDeltaX = getPropertyInt(tokens, 2,
10774 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
10775 mDeltaY = getPropertyInt(tokens, 3,
10776 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
10777 int shadowColor = getPropertyInt(tokens, 4,
10778 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
10779 int color = getPropertyInt(tokens, 5,
10780 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
10781 int shadowRadius = getPropertyInt(tokens, 6,
10782 TypedValue.COMPLEX_UNIT_PX, 7, dm);
10783 int shadowDx = getPropertyInt(tokens, 8,
10784 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10785 int shadowDy = getPropertyInt(tokens, 9,
10786 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10787
10788 mTextPaint.setColor(color);
10789 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010790
10791 try {
10792 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010793 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010794 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010795 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010796 mSurface.show();
10797 } catch (OutOfResourcesException e) {
10798 }
10799 }
10800
10801 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010802 if (mLastDW != dw || mLastDH != dh) {
10803 mLastDW = dw;
10804 mLastDH = dh;
10805 mSurface.setSize(dw, dh);
10806 mDrawNeeded = true;
10807 }
10808 }
10809
10810 void drawIfNeeded() {
10811 if (mDrawNeeded) {
10812 final int dw = mLastDW;
10813 final int dh = mLastDH;
10814
10815 mDrawNeeded = false;
10816 Rect dirty = new Rect(0, 0, dw, dh);
10817 Canvas c = null;
10818 try {
10819 c = mSurface.lockCanvas(dirty);
10820 } catch (IllegalArgumentException e) {
10821 } catch (OutOfResourcesException e) {
10822 }
10823 if (c != null) {
10824 int deltaX = mDeltaX;
10825 int deltaY = mDeltaY;
10826
10827 // deltaX shouldn't be close to a round fraction of our
10828 // x step, or else things will line up too much.
10829 int div = (dw+mTextWidth)/deltaX;
10830 int rem = (dw+mTextWidth) - (div*deltaX);
10831 int qdelta = deltaX/4;
10832 if (rem < qdelta || rem > (deltaX-qdelta)) {
10833 deltaX += deltaX/3;
10834 }
10835
10836 int y = -mTextHeight;
10837 int x = -mTextWidth;
10838 while (y < (dh+mTextHeight)) {
10839 c.drawText(mText, x, y, mTextPaint);
10840 x += deltaX;
10841 if (x >= dw) {
10842 x -= (dw+mTextWidth);
10843 y += deltaY;
10844 }
10845 }
10846 mSurface.unlockCanvasAndPost(c);
10847 }
10848 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010849 }
10850 }
10851
10852 void createWatermark() {
10853 if (mWatermark != null) {
10854 return;
10855 }
10856
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010857 File file = new File("/system/etc/setup.conf");
10858 FileInputStream in = null;
10859 try {
10860 in = new FileInputStream(file);
10861 DataInputStream ind = new DataInputStream(in);
10862 String line = ind.readLine();
10863 if (line != null) {
10864 String[] toks = line.split("%");
10865 if (toks != null && toks.length > 0) {
10866 mWatermark = new Watermark(mFxSession, toks);
10867 }
10868 }
10869 } catch (FileNotFoundException e) {
10870 } catch (IOException e) {
10871 } finally {
10872 if (in != null) {
10873 try {
10874 in.close();
10875 } catch (IOException e) {
10876 }
10877 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010878 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010879 }
10880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 @Override
10882 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10883 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10884 != PackageManager.PERMISSION_GRANTED) {
10885 pw.println("Permission Denial: can't dump WindowManager from from pid="
10886 + Binder.getCallingPid()
10887 + ", uid=" + Binder.getCallingUid());
10888 return;
10889 }
Romain Guy06882f82009-06-10 13:36:04 -070010890
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010891 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080010892 pw.println(" ");
10893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010894 synchronized(mWindowMap) {
10895 pw.println("Current Window Manager state:");
10896 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010897 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010898 pw.print(" Window #"); pw.print(i); pw.print(' ');
10899 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 w.dump(pw, " ");
10901 }
10902 if (mInputMethodDialogs.size() > 0) {
10903 pw.println(" ");
10904 pw.println(" Input method dialogs:");
10905 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10906 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010907 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908 }
10909 }
10910 if (mPendingRemove.size() > 0) {
10911 pw.println(" ");
10912 pw.println(" Remove pending for:");
10913 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10914 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010915 pw.print(" Remove #"); pw.print(i); pw.print(' ');
10916 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010917 w.dump(pw, " ");
10918 }
10919 }
10920 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10921 pw.println(" ");
10922 pw.println(" Windows force removing:");
10923 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10924 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010925 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10926 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010927 w.dump(pw, " ");
10928 }
10929 }
10930 if (mDestroySurface.size() > 0) {
10931 pw.println(" ");
10932 pw.println(" Windows waiting to destroy their surface:");
10933 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10934 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010935 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
10936 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010937 w.dump(pw, " ");
10938 }
10939 }
10940 if (mLosingFocus.size() > 0) {
10941 pw.println(" ");
10942 pw.println(" Windows losing focus:");
10943 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10944 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010945 pw.print(" Losing #"); pw.print(i); pw.print(' ');
10946 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010947 w.dump(pw, " ");
10948 }
10949 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010950 if (mResizingWindows.size() > 0) {
10951 pw.println(" ");
10952 pw.println(" Windows waiting to resize:");
10953 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10954 WindowState w = mResizingWindows.get(i);
10955 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
10956 pw.print(w); pw.println(":");
10957 w.dump(pw, " ");
10958 }
10959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010960 if (mSessions.size() > 0) {
10961 pw.println(" ");
10962 pw.println(" All active sessions:");
10963 Iterator<Session> it = mSessions.iterator();
10964 while (it.hasNext()) {
10965 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010966 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 s.dump(pw, " ");
10968 }
10969 }
10970 if (mTokenMap.size() > 0) {
10971 pw.println(" ");
10972 pw.println(" All tokens:");
10973 Iterator<WindowToken> it = mTokenMap.values().iterator();
10974 while (it.hasNext()) {
10975 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010976 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010977 token.dump(pw, " ");
10978 }
10979 }
10980 if (mTokenList.size() > 0) {
10981 pw.println(" ");
10982 pw.println(" Window token list:");
10983 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010984 pw.print(" #"); pw.print(i); pw.print(": ");
10985 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 }
10987 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010988 if (mWallpaperTokens.size() > 0) {
10989 pw.println(" ");
10990 pw.println(" Wallpaper tokens:");
10991 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10992 WindowToken token = mWallpaperTokens.get(i);
10993 pw.print(" Wallpaper #"); pw.print(i);
10994 pw.print(' '); pw.print(token); pw.println(':');
10995 token.dump(pw, " ");
10996 }
10997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010998 if (mAppTokens.size() > 0) {
10999 pw.println(" ");
11000 pw.println(" Application tokens in Z order:");
11001 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011002 pw.print(" App #"); pw.print(i); pw.print(": ");
11003 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011004 }
11005 }
11006 if (mFinishedStarting.size() > 0) {
11007 pw.println(" ");
11008 pw.println(" Finishing start of application tokens:");
11009 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11010 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011011 pw.print(" Finished Starting #"); pw.print(i);
11012 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 token.dump(pw, " ");
11014 }
11015 }
11016 if (mExitingTokens.size() > 0) {
11017 pw.println(" ");
11018 pw.println(" Exiting tokens:");
11019 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11020 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011021 pw.print(" Exiting #"); pw.print(i);
11022 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011023 token.dump(pw, " ");
11024 }
11025 }
11026 if (mExitingAppTokens.size() > 0) {
11027 pw.println(" ");
11028 pw.println(" Exiting application tokens:");
11029 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11030 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011031 pw.print(" Exiting App #"); pw.print(i);
11032 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 token.dump(pw, " ");
11034 }
11035 }
11036 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011037 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11038 pw.print(" mLastFocus="); pw.println(mLastFocus);
11039 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11040 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11041 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011042 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011043 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11044 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11045 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11046 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011047 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11048 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11049 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011050 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11051 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11052 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11053 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011054 if (mDimAnimator != null) {
11055 mDimAnimator.printTo(pw);
11056 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011057 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011058 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011059 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011060 pw.print(mInputMethodAnimLayerAdjustment);
11061 pw.print(" mWallpaperAnimLayerAdjustment=");
11062 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011063 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11064 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011065 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11066 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011067 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11068 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011069 pw.print(" mRotation="); pw.print(mRotation);
11070 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11071 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11072 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11073 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11074 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11075 pw.print(" mNextAppTransition=0x");
11076 pw.print(Integer.toHexString(mNextAppTransition));
11077 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011078 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011079 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011080 if (mNextAppTransitionPackage != null) {
11081 pw.print(" mNextAppTransitionPackage=");
11082 pw.print(mNextAppTransitionPackage);
11083 pw.print(", mNextAppTransitionEnter=0x");
11084 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11085 pw.print(", mNextAppTransitionExit=0x");
11086 pw.print(Integer.toHexString(mNextAppTransitionExit));
11087 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011088 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11089 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011090 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11091 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11092 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11093 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011094 if (mOpeningApps.size() > 0) {
11095 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11096 }
11097 if (mClosingApps.size() > 0) {
11098 pw.print(" mClosingApps="); pw.println(mClosingApps);
11099 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011100 if (mToTopApps.size() > 0) {
11101 pw.print(" mToTopApps="); pw.println(mToTopApps);
11102 }
11103 if (mToBottomApps.size() > 0) {
11104 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11105 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011106 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11107 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 }
11109 }
11110
Jeff Brown349703e2010-06-22 01:27:15 -070011111 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011112 public void monitor() {
11113 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011114 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011115 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011116
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011117 /**
11118 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011119 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011120 */
11121 private static class DimAnimator {
11122 Surface mDimSurface;
11123 boolean mDimShown = false;
11124 float mDimCurrentAlpha;
11125 float mDimTargetAlpha;
11126 float mDimDeltaPerMs;
11127 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011128
11129 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011130
11131 DimAnimator (SurfaceSession session) {
11132 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011133 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011134 + mDimSurface + ": CREATE");
11135 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011136 mDimSurface = new Surface(session, 0,
11137 "DimSurface",
11138 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011139 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011140 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011141 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011142 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011143 }
11144 }
11145 }
11146
11147 /**
11148 * Show the dim surface.
11149 */
11150 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011151 if (!mDimShown) {
11152 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11153 dw + "x" + dh + ")");
11154 mDimShown = true;
11155 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011156 mLastDimWidth = dw;
11157 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011158 mDimSurface.setPosition(0, 0);
11159 mDimSurface.setSize(dw, dh);
11160 mDimSurface.show();
11161 } catch (RuntimeException e) {
11162 Slog.w(TAG, "Failure showing dim surface", e);
11163 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011164 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11165 mLastDimWidth = dw;
11166 mLastDimHeight = dh;
11167 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011168 }
11169 }
11170
11171 /**
11172 * Set's the dim surface's layer and update dim parameters that will be used in
11173 * {@link updateSurface} after all windows are examined.
11174 */
11175 void updateParameters(WindowState w, long currentTime) {
11176 mDimSurface.setLayer(w.mAnimLayer-1);
11177
11178 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011179 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011180 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011181 if (mDimTargetAlpha != target) {
11182 // If the desired dim level has changed, then
11183 // start an animation to it.
11184 mLastDimAnimTime = currentTime;
11185 long duration = (w.mAnimating && w.mAnimation != null)
11186 ? w.mAnimation.computeDurationHint()
11187 : DEFAULT_DIM_DURATION;
11188 if (target > mDimTargetAlpha) {
11189 // This is happening behind the activity UI,
11190 // so we can make it run a little longer to
11191 // give a stronger impression without disrupting
11192 // the user.
11193 duration *= DIM_DURATION_MULTIPLIER;
11194 }
11195 if (duration < 1) {
11196 // Don't divide by zero
11197 duration = 1;
11198 }
11199 mDimTargetAlpha = target;
11200 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11201 }
11202 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011203
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011204 /**
11205 * Updating the surface's alpha. Returns true if the animation continues, or returns
11206 * false when the animation is finished and the dim surface is hidden.
11207 */
11208 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11209 if (!dimming) {
11210 if (mDimTargetAlpha != 0) {
11211 mLastDimAnimTime = currentTime;
11212 mDimTargetAlpha = 0;
11213 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11214 }
11215 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011216
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011217 boolean animating = false;
11218 if (mLastDimAnimTime != 0) {
11219 mDimCurrentAlpha += mDimDeltaPerMs
11220 * (currentTime-mLastDimAnimTime);
11221 boolean more = true;
11222 if (displayFrozen) {
11223 // If the display is frozen, there is no reason to animate.
11224 more = false;
11225 } else if (mDimDeltaPerMs > 0) {
11226 if (mDimCurrentAlpha > mDimTargetAlpha) {
11227 more = false;
11228 }
11229 } else if (mDimDeltaPerMs < 0) {
11230 if (mDimCurrentAlpha < mDimTargetAlpha) {
11231 more = false;
11232 }
11233 } else {
11234 more = false;
11235 }
11236
11237 // Do we need to continue animating?
11238 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011239 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011240 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11241 mLastDimAnimTime = currentTime;
11242 mDimSurface.setAlpha(mDimCurrentAlpha);
11243 animating = true;
11244 } else {
11245 mDimCurrentAlpha = mDimTargetAlpha;
11246 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011247 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011248 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11249 mDimSurface.setAlpha(mDimCurrentAlpha);
11250 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011251 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011252 + ": HIDE");
11253 try {
11254 mDimSurface.hide();
11255 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011256 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011257 }
11258 mDimShown = false;
11259 }
11260 }
11261 }
11262 return animating;
11263 }
11264
11265 public void printTo(PrintWriter pw) {
11266 pw.print(" mDimShown="); pw.print(mDimShown);
11267 pw.print(" current="); pw.print(mDimCurrentAlpha);
11268 pw.print(" target="); pw.print(mDimTargetAlpha);
11269 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11270 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11271 }
11272 }
11273
11274 /**
11275 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11276 * This is used for opening/closing transition for apps in compatible mode.
11277 */
11278 private static class FadeInOutAnimation extends Animation {
11279 int mWidth;
11280 boolean mFadeIn;
11281
11282 public FadeInOutAnimation(boolean fadeIn) {
11283 setInterpolator(new AccelerateInterpolator());
11284 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11285 mFadeIn = fadeIn;
11286 }
11287
11288 @Override
11289 protected void applyTransformation(float interpolatedTime, Transformation t) {
11290 float x = interpolatedTime;
11291 if (!mFadeIn) {
11292 x = 1.0f - x; // reverse the interpolation for fade out
11293 }
11294 if (x < 0.5) {
11295 // move the window out of the screen.
11296 t.getMatrix().setTranslate(mWidth, 0);
11297 } else {
11298 t.getMatrix().setTranslate(0, 0);// show
11299 t.setAlpha((x - 0.5f) * 2);
11300 }
11301 }
11302
11303 @Override
11304 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11305 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11306 mWidth = width;
11307 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011308
11309 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011310 public int getZAdjustment() {
11311 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011312 }
11313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011314}