blob: 0c1417d3ecea0cd900bfbefb33eb731b4f458559 [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;
502 ClipData mData;
503 ClipDescription mDataDescription;
504 float mThumbOffsetX, mThumbOffsetY;
505 InputChannel mServerChannel, mClientChannel;
506 WindowState mTargetWindow;
507 ArrayList<WindowState> mNotifiedWindows;
508 boolean mDragEnded;
509
510 private final Rect tmpRect = new Rect();
511
512 DragState(IBinder token, Surface surface, boolean localOnly) {
513 mToken = token;
514 mSurface = surface;
515 mLocalOnly = localOnly;
516 mNotifiedWindows = new ArrayList<WindowState>();
517 }
518
519 void reset() {
520 if (mSurface != null) {
521 mSurface.destroy();
522 }
523 mSurface = null;
524 mLocalOnly = false;
525 mToken = null;
526 mData = null;
527 mThumbOffsetX = mThumbOffsetY = 0;
528 mNotifiedWindows = null;
529 }
530
531 void register() {
532 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
533 if (mClientChannel != null) {
534 Slog.e(TAG, "Duplicate register of drag input channel");
535 } else {
536 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
537 mServerChannel = channels[0];
538 mClientChannel = channels[1];
539 mInputManager.registerInputChannel(mServerChannel);
540 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
541 mH.getLooper().getQueue());
542 }
543 }
544
545 void unregister() {
546 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
547 if (mClientChannel == null) {
548 Slog.e(TAG, "Unregister of nonexistent drag input channel");
549 } else {
550 mInputManager.unregisterInputChannel(mServerChannel);
551 InputQueue.unregisterInputChannel(mClientChannel);
552 mClientChannel.dispose();
553 mClientChannel = null;
554 mServerChannel = null;
555 }
556 }
557
558 /* call out to each visible window/session informing it about the drag
559 */
560 void broadcastDragStartedLw() {
561 // Cache a base-class instance of the clip metadata so that parceling
562 // works correctly in calling out to the apps.
563 mDataDescription = new ClipDescription(mData);
564 mNotifiedWindows.clear();
565
566 if (DEBUG_DRAG) {
567 Slog.d(TAG, "broadcasting DRAG_STARTED of " + mDataDescription);
568 }
569
570 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
571 mDataDescription, null);
572 for (WindowState ws : mWindows) {
573 sendDragStartedLw(ws, evt);
574 }
575 evt.recycle();
576 }
577
578 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
579 * designated window is potentially a drop recipient. There are race situations
580 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
581 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
582 */
583 private void sendDragStartedLw(WindowState newWin, final DragEvent event) {
584 if (!mDragEnded && newWin.isPotentialDragTarget()) {
585 try {
586 newWin.mClient.dispatchDragEvent(event);
587 // track each window that we've notified that the drag is starting
588 mNotifiedWindows.add(newWin);
589 } catch (RemoteException e) {
590 Slog.w(TAG, "Unable to drag-start window " + newWin);
591 }
592 }
593 }
594
595 /* helper - construct and send a DRAG_STARTED event only if the window has not
596 * previously been notified, i.e. it became visible after the drag operation
597 * was begun. This is a rare case.
598 */
599 private void sendDragStartedIfNeededLw(WindowState newWin) {
600 // If we have sent the drag-started, we needn't do so again
601 for (WindowState ws : mNotifiedWindows) {
602 if (ws == newWin) {
603 return;
604 }
605 }
606 if (DEBUG_DRAG) {
607 Slog.d(TAG, "sending DRAG_STARTED to new window " + newWin);
608 }
609 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
610 mDataDescription, null);
611 sendDragStartedLw(newWin, event);
612 event.recycle();
613 }
614
615 void broadcastDragEnded() {
616 if (DEBUG_DRAG) {
617 Slog.d(TAG, "broadcasting DRAG_ENDED");
618 }
619 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, 0, 0, null, null);
620 synchronized (mWindowMap) {
621 for (WindowState ws: mNotifiedWindows) {
622 try {
623 ws.mClient.dispatchDragEvent(evt);
624 } catch (RemoteException e) {
625 Slog.w(TAG, "Unable to drag-end window " + ws);
626 }
627 }
628 mNotifiedWindows.clear();
629 mDragEnded = true;
630 }
631 evt.recycle();
632 }
633
634 void notifyMoveLw(float x, float y) {
635 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
636 try {
637 // have we dragged over a new window?
638 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
639 if (DEBUG_DRAG) {
640 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
641 }
642 // force DRAG_EXITED_EVENT if appropriate
643 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
644 0, 0, null, null);
645 mTargetWindow.mClient.dispatchDragEvent(evt);
646 evt.recycle();
647 }
648 if (touchedWin != null) {
649 if (DEBUG_DRAG) {
650 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
651 }
652 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
653 x, y, null, null);
654 touchedWin.mClient.dispatchDragEvent(evt);
655 evt.recycle();
656 }
657 } catch (RemoteException e) {
658 Slog.w(TAG, "can't send drag notification to windows");
659 }
660 mTargetWindow = touchedWin;
661 }
662
663 // Tell the drop target about the data, and then broadcast the drag-ended notification
664 void notifyDropLw(float x, float y) {
665 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
666 if (touchedWin != null) {
667 if (DEBUG_DRAG) {
668 Slog.d(TAG, "sending DROP to " + touchedWin);
669 }
670 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x, y, null, mData);
671 try {
672 touchedWin.mClient.dispatchDragEvent(evt);
673 } catch (RemoteException e) {
674 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
675 }
676 evt.recycle();
677 }
678 }
679
680 // Find the visible, touch-deliverable window under the given point
681 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
682 WindowState touchedWin = null;
683 final int x = (int) xf;
684 final int y = (int) yf;
685 final ArrayList<WindowState> windows = mWindows;
686 final int N = windows.size();
687 for (int i = N - 1; i >= 0; i--) {
688 WindowState child = windows.get(i);
689 final int flags = child.mAttrs.flags;
690 if (!child.isVisibleLw()) {
691 // not visible == don't tell about drags
692 continue;
693 }
694 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
695 // not touchable == don't tell about drags
696 continue;
697 }
698 // account for the window's decor etc
699 tmpRect.set(child.mFrame);
700 if (child.mTouchableInsets == ViewTreeObserver
701 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
702 // The point is inside of the window if it is
703 // inside the frame, AND the content part of that
704 // frame that was given by the application.
705 tmpRect.left += child.mGivenContentInsets.left;
706 tmpRect.top += child.mGivenContentInsets.top;
707 tmpRect.right -= child.mGivenContentInsets.right;
708 tmpRect.bottom -= child.mGivenContentInsets.bottom;
709 } else if (child.mTouchableInsets == ViewTreeObserver
710 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
711 // The point is inside of the window if it is
712 // inside the frame, AND the visible part of that
713 // frame that was given by the application.
714 tmpRect.left += child.mGivenVisibleInsets.left;
715 tmpRect.top += child.mGivenVisibleInsets.top;
716 tmpRect.right -= child.mGivenVisibleInsets.right;
717 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
718 }
719 final int touchFlags = flags &
720 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
721 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
722 if (tmpRect.contains(x, y) || touchFlags == 0) {
723 // Found it
724 touchedWin = child;
725 break;
726 }
727 }
728
729 return touchedWin;
730 }
731 }
732
733 DragState mDragState = null;
734 private final InputHandler mDragInputHandler = new BaseInputHandler() {
735 @Override
736 public void handleMotion(MotionEvent event, Runnable finishedCallback) {
737 boolean endDrag = false;
738 final float newX = event.getRawX();
739 final float newY = event.getRawY();
740
741 try {
742 if (mDragState != null) {
743 switch (event.getAction()) {
744 case MotionEvent.ACTION_DOWN: {
745 if (DEBUG_DRAG) {
746 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
747 }
748 } break;
749
750 case MotionEvent.ACTION_MOVE: {
751 synchronized (mWindowMap) {
752 // move the surface to the latest touch point
753 mDragState.mSurface.openTransaction();
754 mDragState.mSurface.setPosition((int)(newX - mDragState.mThumbOffsetX),
755 (int)(newY - mDragState.mThumbOffsetY));
756 mDragState.mSurface.closeTransaction();
757
758 // tell the involved window(s) where we are
759 mDragState.notifyMoveLw(newX, newY);
760 }
761 } break;
762
763 case MotionEvent.ACTION_UP: {
764 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
765 + newX + "," + newY);
766 synchronized (mWindowMap) {
767 mDragState.notifyDropLw(newX, newY);
768 }
769 endDrag = true;
770 } break;
771
772 case MotionEvent.ACTION_CANCEL: {
773 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
774 endDrag = true;
775 } break;
776 }
777
778 if (endDrag) {
779 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
780 // tell all the windows that the drag has ended
781 mDragState.broadcastDragEnded();
782
783 // stop intercepting input
784 mDragState.unregister();
785 mInputMonitor.updateInputWindowsLw();
786
787 // free our resources and drop all the object references
788 mDragState.reset();
789 mDragState = null;
790 }
791 }
792 } catch (Exception e) {
793 Slog.e(TAG, "Exception caught by drag handleMotion", e);
794 } finally {
795 finishedCallback.run();
796 }
797 }
798 };
799
800 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 * Whether the UI is currently running in touch mode (not showing
802 * navigational focus because the user is directly pressing the screen).
803 */
804 boolean mInTouchMode = false;
805
806 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700807 private ArrayList<WindowChangeListener> mWindowChangeListeners =
808 new ArrayList<WindowChangeListener>();
809 private boolean mWindowsChanged = false;
810
811 public interface WindowChangeListener {
812 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700813 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815
Dianne Hackbornc485a602009-03-24 22:39:49 -0700816 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700817 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700818
819 // The frame use to limit the size of the app running in compatibility mode.
820 Rect mCompatibleScreenFrame = new Rect();
821 // The surface used to fill the outer rim of the app running in compatibility mode.
822 Surface mBackgroundFillerSurface = null;
823 boolean mBackgroundFillerShown = false;
824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 public static WindowManagerService main(Context context,
826 PowerManagerService pm, boolean haveInputMethods) {
827 WMThread thr = new WMThread(context, pm, haveInputMethods);
828 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 synchronized (thr) {
831 while (thr.mService == null) {
832 try {
833 thr.wait();
834 } catch (InterruptedException e) {
835 }
836 }
837 }
Romain Guy06882f82009-06-10 13:36:04 -0700838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 return thr.mService;
840 }
Romain Guy06882f82009-06-10 13:36:04 -0700841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 static class WMThread extends Thread {
843 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 private final Context mContext;
846 private final PowerManagerService mPM;
847 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 public WMThread(Context context, PowerManagerService pm,
850 boolean haveInputMethods) {
851 super("WindowManager");
852 mContext = context;
853 mPM = pm;
854 mHaveInputMethods = haveInputMethods;
855 }
Romain Guy06882f82009-06-10 13:36:04 -0700856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 public void run() {
858 Looper.prepare();
859 WindowManagerService s = new WindowManagerService(mContext, mPM,
860 mHaveInputMethods);
861 android.os.Process.setThreadPriority(
862 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700863 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 synchronized (this) {
866 mService = s;
867 notifyAll();
868 }
Romain Guy06882f82009-06-10 13:36:04 -0700869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 Looper.loop();
871 }
872 }
873
874 static class PolicyThread extends Thread {
875 private final WindowManagerPolicy mPolicy;
876 private final WindowManagerService mService;
877 private final Context mContext;
878 private final PowerManagerService mPM;
879 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 public PolicyThread(WindowManagerPolicy policy,
882 WindowManagerService service, Context context,
883 PowerManagerService pm) {
884 super("WindowManagerPolicy");
885 mPolicy = policy;
886 mService = service;
887 mContext = context;
888 mPM = pm;
889 }
Romain Guy06882f82009-06-10 13:36:04 -0700890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 public void run() {
892 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800893 WindowManagerPolicyThread.set(this, Looper.myLooper());
894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800896 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 android.os.Process.setThreadPriority(
898 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700899 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 synchronized (this) {
903 mRunning = true;
904 notifyAll();
905 }
Romain Guy06882f82009-06-10 13:36:04 -0700906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 Looper.loop();
908 }
909 }
910
911 private WindowManagerService(Context context, PowerManagerService pm,
912 boolean haveInputMethods) {
913 mContext = context;
914 mHaveInputMethods = haveInputMethods;
915 mLimitedAlphaCompositing = context.getResources().getBoolean(
916 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 mPowerManager = pm;
919 mPowerManager.setPolicy(mPolicy);
920 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
921 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
922 "SCREEN_FROZEN");
923 mScreenFrozenLock.setReferenceCounted(false);
924
925 mActivityManager = ActivityManagerNative.getDefault();
926 mBatteryStats = BatteryStatsService.getService();
927
928 // Get persisted window scale setting
929 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
930 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
931 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
932 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700933
Jim Miller284b62e2010-06-08 14:27:42 -0700934 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
935 IntentFilter filter = new IntentFilter();
936 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
937 mContext.registerReceiver(mBroadcastReceiver, filter);
938
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700939 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
940 "KEEP_SCREEN_ON_FLAG");
941 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942
Jeff Browne33348b2010-07-15 23:54:05 -0700943 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
946 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 synchronized (thr) {
949 while (!thr.mRunning) {
950 try {
951 thr.wait();
952 } catch (InterruptedException e) {
953 }
954 }
955 }
Romain Guy06882f82009-06-10 13:36:04 -0700956
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700957 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 // Add ourself to the Watchdog monitors.
960 Watchdog.getInstance().addMonitor(this);
961 }
962
963 @Override
964 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
965 throws RemoteException {
966 try {
967 return super.onTransact(code, data, reply, flags);
968 } catch (RuntimeException e) {
969 // The window manager only throws security exceptions, so let's
970 // log all others.
971 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800972 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 }
974 throw e;
975 }
976 }
977
Jeff Browne33348b2010-07-15 23:54:05 -0700978 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800980 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 TAG, "Adding window " + window + " at "
982 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
983 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700984 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 }
986
Jeff Browne33348b2010-07-15 23:54:05 -0700987 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800989 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 TAG, "Adding window " + window + " at "
991 + i + " of " + mWindows.size() + " (before " + pos + ")");
992 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700993 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995
996 //This method finds out the index of a window that has the same app token as
997 //win. used for z ordering the windows in mWindows
998 private int findIdxBasedOnAppTokens(WindowState win) {
999 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001000 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 int jmax = localmWindows.size();
1002 if(jmax == 0) {
1003 return -1;
1004 }
1005 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001006 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 if(wentry.mAppToken == win.mAppToken) {
1008 return j;
1009 }
1010 }
1011 return -1;
1012 }
Romain Guy06882f82009-06-10 13:36:04 -07001013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1015 final IWindow client = win.mClient;
1016 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001017 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 final int N = localmWindows.size();
1020 final WindowState attached = win.mAttachedWindow;
1021 int i;
1022 if (attached == null) {
1023 int tokenWindowsPos = token.windows.size();
1024 if (token.appWindowToken != null) {
1025 int index = tokenWindowsPos-1;
1026 if (index >= 0) {
1027 // If this application has existing windows, we
1028 // simply place the new window on top of them... but
1029 // keep the starting window on top.
1030 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1031 // Base windows go behind everything else.
1032 placeWindowBefore(token.windows.get(0), win);
1033 tokenWindowsPos = 0;
1034 } else {
1035 AppWindowToken atoken = win.mAppToken;
1036 if (atoken != null &&
1037 token.windows.get(index) == atoken.startingWindow) {
1038 placeWindowBefore(token.windows.get(index), win);
1039 tokenWindowsPos--;
1040 } else {
1041 int newIdx = findIdxBasedOnAppTokens(win);
1042 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001043 //there is a window above this one associated with the same
1044 //apptoken note that the window could be a floating window
1045 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001047 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001048 TAG, "Adding window " + win + " at "
1049 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001051 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 }
1054 }
1055 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001056 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 TAG, "Figuring out where to add app window "
1058 + client.asBinder() + " (token=" + token + ")");
1059 // Figure out where the window should go, based on the
1060 // order of applications.
1061 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001062 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 for (i=NA-1; i>=0; i--) {
1064 AppWindowToken t = mAppTokens.get(i);
1065 if (t == token) {
1066 i--;
1067 break;
1068 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001069
Dianne Hackborna8f60182009-09-01 19:01:50 -07001070 // We haven't reached the token yet; if this token
1071 // is not going to the bottom and has windows, we can
1072 // use it as an anchor for when we do reach the token.
1073 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 pos = t.windows.get(0);
1075 }
1076 }
1077 // We now know the index into the apps. If we found
1078 // an app window above, that gives us the position; else
1079 // we need to look some more.
1080 if (pos != null) {
1081 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001082 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 if (atoken != null) {
1084 final int NC = atoken.windows.size();
1085 if (NC > 0) {
1086 WindowState bottom = atoken.windows.get(0);
1087 if (bottom.mSubLayer < 0) {
1088 pos = bottom;
1089 }
1090 }
1091 }
1092 placeWindowBefore(pos, win);
1093 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001094 // Continue looking down until we find the first
1095 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 while (i >= 0) {
1097 AppWindowToken t = mAppTokens.get(i);
1098 final int NW = t.windows.size();
1099 if (NW > 0) {
1100 pos = t.windows.get(NW-1);
1101 break;
1102 }
1103 i--;
1104 }
1105 if (pos != null) {
1106 // Move in front of any windows attached to this
1107 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001108 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 if (atoken != null) {
1110 final int NC = atoken.windows.size();
1111 if (NC > 0) {
1112 WindowState top = atoken.windows.get(NC-1);
1113 if (top.mSubLayer >= 0) {
1114 pos = top;
1115 }
1116 }
1117 }
1118 placeWindowAfter(pos, win);
1119 } else {
1120 // Just search for the start of this layer.
1121 final int myLayer = win.mBaseLayer;
1122 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001123 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 if (w.mBaseLayer > myLayer) {
1125 break;
1126 }
1127 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001128 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001129 TAG, "Adding window " + win + " at "
1130 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001132 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 }
1134 }
1135 }
1136 } else {
1137 // Figure out where window should go, based on layer.
1138 final int myLayer = win.mBaseLayer;
1139 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001140 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 i++;
1142 break;
1143 }
1144 }
1145 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001146 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001147 TAG, "Adding window " + win + " at "
1148 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001150 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 }
1152 if (addToToken) {
1153 token.windows.add(tokenWindowsPos, win);
1154 }
1155
1156 } else {
1157 // Figure out this window's ordering relative to the window
1158 // it is attached to.
1159 final int NA = token.windows.size();
1160 final int sublayer = win.mSubLayer;
1161 int largestSublayer = Integer.MIN_VALUE;
1162 WindowState windowWithLargestSublayer = null;
1163 for (i=0; i<NA; i++) {
1164 WindowState w = token.windows.get(i);
1165 final int wSublayer = w.mSubLayer;
1166 if (wSublayer >= largestSublayer) {
1167 largestSublayer = wSublayer;
1168 windowWithLargestSublayer = w;
1169 }
1170 if (sublayer < 0) {
1171 // For negative sublayers, we go below all windows
1172 // in the same sublayer.
1173 if (wSublayer >= sublayer) {
1174 if (addToToken) {
1175 token.windows.add(i, win);
1176 }
1177 placeWindowBefore(
1178 wSublayer >= 0 ? attached : w, win);
1179 break;
1180 }
1181 } else {
1182 // For positive sublayers, we go above all windows
1183 // in the same sublayer.
1184 if (wSublayer > sublayer) {
1185 if (addToToken) {
1186 token.windows.add(i, win);
1187 }
1188 placeWindowBefore(w, win);
1189 break;
1190 }
1191 }
1192 }
1193 if (i >= NA) {
1194 if (addToToken) {
1195 token.windows.add(win);
1196 }
1197 if (sublayer < 0) {
1198 placeWindowBefore(attached, win);
1199 } else {
1200 placeWindowAfter(largestSublayer >= 0
1201 ? windowWithLargestSublayer
1202 : attached,
1203 win);
1204 }
1205 }
1206 }
Romain Guy06882f82009-06-10 13:36:04 -07001207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 if (win.mAppToken != null && addToToken) {
1209 win.mAppToken.allAppWindows.add(win);
1210 }
1211 }
Romain Guy06882f82009-06-10 13:36:04 -07001212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 static boolean canBeImeTarget(WindowState w) {
1214 final int fl = w.mAttrs.flags
1215 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1216 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1217 return w.isVisibleOrAdding();
1218 }
1219 return false;
1220 }
Romain Guy06882f82009-06-10 13:36:04 -07001221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001223 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 final int N = localmWindows.size();
1225 WindowState w = null;
1226 int i = N;
1227 while (i > 0) {
1228 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001229 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001230
Joe Onorato8a9b2202010-02-26 18:56:32 -08001231 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 // + Integer.toHexString(w.mAttrs.flags));
1233 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001234 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 // Yet more tricksyness! If this window is a "starting"
1237 // window, we do actually want to be on top of it, but
1238 // it is not -really- where input will go. So if the caller
1239 // is not actually looking to move the IME, look down below
1240 // for a real window to target...
1241 if (!willMove
1242 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1243 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001244 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1246 i--;
1247 w = wb;
1248 }
1249 }
1250 break;
1251 }
1252 }
Romain Guy06882f82009-06-10 13:36:04 -07001253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -07001255
Joe Onorato8a9b2202010-02-26 18:56:32 -08001256 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 if (willMove && w != null) {
1260 final WindowState curTarget = mInputMethodTarget;
1261 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 // Now some fun for dealing with window animations that
1264 // modify the Z order. We need to look at all windows below
1265 // the current target that are in this app, finding the highest
1266 // visible one in layering.
1267 AppWindowToken token = curTarget.mAppToken;
1268 WindowState highestTarget = null;
1269 int highestPos = 0;
1270 if (token.animating || token.animation != null) {
1271 int pos = 0;
1272 pos = localmWindows.indexOf(curTarget);
1273 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001274 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 if (win.mAppToken != token) {
1276 break;
1277 }
1278 if (!win.mRemoved) {
1279 if (highestTarget == null || win.mAnimLayer >
1280 highestTarget.mAnimLayer) {
1281 highestTarget = win;
1282 highestPos = pos;
1283 }
1284 }
1285 pos--;
1286 }
1287 }
Romain Guy06882f82009-06-10 13:36:04 -07001288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001290 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 + mNextAppTransition + " " + highestTarget
1292 + " animating=" + highestTarget.isAnimating()
1293 + " layer=" + highestTarget.mAnimLayer
1294 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001295
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001296 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 // If we are currently setting up for an animation,
1298 // hold everything until we can find out what will happen.
1299 mInputMethodTargetWaitingAnim = true;
1300 mInputMethodTarget = highestTarget;
1301 return highestPos + 1;
1302 } else if (highestTarget.isAnimating() &&
1303 highestTarget.mAnimLayer > w.mAnimLayer) {
1304 // If the window we are currently targeting is involved
1305 // with an animation, and it is on top of the next target
1306 // we will be over, then hold off on moving until
1307 // that is done.
1308 mInputMethodTarget = highestTarget;
1309 return highestPos + 1;
1310 }
1311 }
1312 }
1313 }
Romain Guy06882f82009-06-10 13:36:04 -07001314
Joe Onorato8a9b2202010-02-26 18:56:32 -08001315 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 if (w != null) {
1317 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001318 if (DEBUG_INPUT_METHOD) {
1319 RuntimeException e = null;
1320 if (!HIDE_STACK_CRAWLS) {
1321 e = new RuntimeException();
1322 e.fillInStackTrace();
1323 }
1324 Slog.w(TAG, "Moving IM target from "
1325 + mInputMethodTarget + " to " + w, e);
1326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 mInputMethodTarget = w;
1328 if (w.mAppToken != null) {
1329 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1330 } else {
1331 setInputMethodAnimLayerAdjustment(0);
1332 }
1333 }
1334 return i+1;
1335 }
1336 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001337 if (DEBUG_INPUT_METHOD) {
1338 RuntimeException e = null;
1339 if (!HIDE_STACK_CRAWLS) {
1340 e = new RuntimeException();
1341 e.fillInStackTrace();
1342 }
1343 Slog.w(TAG, "Moving IM target from "
1344 + mInputMethodTarget + " to null", e);
1345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 mInputMethodTarget = null;
1347 setInputMethodAnimLayerAdjustment(0);
1348 }
1349 return -1;
1350 }
Romain Guy06882f82009-06-10 13:36:04 -07001351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 void addInputMethodWindowToListLocked(WindowState win) {
1353 int pos = findDesiredInputMethodWindowIndexLocked(true);
1354 if (pos >= 0) {
1355 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001356 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001357 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001359 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 moveInputMethodDialogsLocked(pos+1);
1361 return;
1362 }
1363 win.mTargetAppToken = null;
1364 addWindowToListInOrderLocked(win, true);
1365 moveInputMethodDialogsLocked(pos);
1366 }
Romain Guy06882f82009-06-10 13:36:04 -07001367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001369 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 mInputMethodAnimLayerAdjustment = adj;
1371 WindowState imw = mInputMethodWindow;
1372 if (imw != null) {
1373 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001374 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 + " anim layer: " + imw.mAnimLayer);
1376 int wi = imw.mChildWindows.size();
1377 while (wi > 0) {
1378 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001379 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001381 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 + " anim layer: " + cw.mAnimLayer);
1383 }
1384 }
1385 int di = mInputMethodDialogs.size();
1386 while (di > 0) {
1387 di --;
1388 imw = mInputMethodDialogs.get(di);
1389 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001390 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 + " anim layer: " + imw.mAnimLayer);
1392 }
1393 }
Romain Guy06882f82009-06-10 13:36:04 -07001394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1396 int wpos = mWindows.indexOf(win);
1397 if (wpos >= 0) {
1398 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001399 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001401 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 int NC = win.mChildWindows.size();
1403 while (NC > 0) {
1404 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001405 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 int cpos = mWindows.indexOf(cw);
1407 if (cpos >= 0) {
1408 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001409 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001410 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 mWindows.remove(cpos);
1412 }
1413 }
1414 }
1415 return interestingPos;
1416 }
Romain Guy06882f82009-06-10 13:36:04 -07001417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 private void reAddWindowToListInOrderLocked(WindowState win) {
1419 addWindowToListInOrderLocked(win, false);
1420 // This is a hack to get all of the child windows added as well
1421 // at the right position. Child windows should be rare and
1422 // this case should be rare, so it shouldn't be that big a deal.
1423 int wpos = mWindows.indexOf(win);
1424 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001425 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001426 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001428 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 reAddWindowLocked(wpos, win);
1430 }
1431 }
Romain Guy06882f82009-06-10 13:36:04 -07001432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 void logWindowList(String prefix) {
1434 int N = mWindows.size();
1435 while (N > 0) {
1436 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 }
1439 }
Romain Guy06882f82009-06-10 13:36:04 -07001440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 void moveInputMethodDialogsLocked(int pos) {
1442 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001445 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 for (int i=0; i<N; i++) {
1447 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1448 }
1449 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 logWindowList(" ");
1452 }
Romain Guy06882f82009-06-10 13:36:04 -07001453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 if (pos >= 0) {
1455 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1456 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001457 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 if (wp == mInputMethodWindow) {
1459 pos++;
1460 }
1461 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001462 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 for (int i=0; i<N; i++) {
1464 WindowState win = dialogs.get(i);
1465 win.mTargetAppToken = targetAppToken;
1466 pos = reAddWindowLocked(pos, win);
1467 }
1468 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001469 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 logWindowList(" ");
1471 }
1472 return;
1473 }
1474 for (int i=0; i<N; i++) {
1475 WindowState win = dialogs.get(i);
1476 win.mTargetAppToken = null;
1477 reAddWindowToListInOrderLocked(win);
1478 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 logWindowList(" ");
1481 }
1482 }
1483 }
Romain Guy06882f82009-06-10 13:36:04 -07001484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1486 final WindowState imWin = mInputMethodWindow;
1487 final int DN = mInputMethodDialogs.size();
1488 if (imWin == null && DN == 0) {
1489 return false;
1490 }
Romain Guy06882f82009-06-10 13:36:04 -07001491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1493 if (imPos >= 0) {
1494 // In this case, the input method windows are to be placed
1495 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 // First check to see if the input method windows are already
1498 // located here, and contiguous.
1499 final int N = mWindows.size();
1500 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001501 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 // Figure out the actual input method window that should be
1504 // at the bottom of their stack.
1505 WindowState baseImWin = imWin != null
1506 ? imWin : mInputMethodDialogs.get(0);
1507 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001508 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 if (cw.mSubLayer < 0) baseImWin = cw;
1510 }
Romain Guy06882f82009-06-10 13:36:04 -07001511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 if (firstImWin == baseImWin) {
1513 // The windows haven't moved... but are they still contiguous?
1514 // First find the top IM window.
1515 int pos = imPos+1;
1516 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001517 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 break;
1519 }
1520 pos++;
1521 }
1522 pos++;
1523 // Now there should be no more input method windows above.
1524 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001525 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 break;
1527 }
1528 pos++;
1529 }
1530 if (pos >= N) {
1531 // All is good!
1532 return false;
1533 }
1534 }
Romain Guy06882f82009-06-10 13:36:04 -07001535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 if (imWin != null) {
1537 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001538 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 logWindowList(" ");
1540 }
1541 imPos = tmpRemoveWindowLocked(imPos, imWin);
1542 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001543 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 logWindowList(" ");
1545 }
1546 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1547 reAddWindowLocked(imPos, imWin);
1548 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001549 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 logWindowList(" ");
1551 }
1552 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1553 } else {
1554 moveInputMethodDialogsLocked(imPos);
1555 }
Romain Guy06882f82009-06-10 13:36:04 -07001556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 } else {
1558 // In this case, the input method windows go in a fixed layer,
1559 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001562 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 tmpRemoveWindowLocked(0, imWin);
1564 imWin.mTargetAppToken = null;
1565 reAddWindowToListInOrderLocked(imWin);
1566 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001567 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 logWindowList(" ");
1569 }
1570 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1571 } else {
1572 moveInputMethodDialogsLocked(-1);;
1573 }
Romain Guy06882f82009-06-10 13:36:04 -07001574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 }
Romain Guy06882f82009-06-10 13:36:04 -07001576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 if (needAssignLayers) {
1578 assignLayersLocked();
1579 }
Romain Guy06882f82009-06-10 13:36:04 -07001580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 return true;
1582 }
Romain Guy06882f82009-06-10 13:36:04 -07001583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 void adjustInputMethodDialogsLocked() {
1585 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1586 }
Romain Guy06882f82009-06-10 13:36:04 -07001587
Dianne Hackborn25994b42009-09-04 14:21:19 -07001588 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001589 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001590 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1591 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1592 ? wallpaperTarget.mAppToken.animation : null)
1593 + " upper=" + mUpperWallpaperTarget
1594 + " lower=" + mLowerWallpaperTarget);
1595 return (wallpaperTarget != null
1596 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1597 && wallpaperTarget.mAppToken.animation != null)))
1598 || mUpperWallpaperTarget != null
1599 || mLowerWallpaperTarget != null;
1600 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001601
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001602 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1603 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001604
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001605 int adjustWallpaperWindowsLocked() {
1606 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001607
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001608 final int dw = mDisplay.getWidth();
1609 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001610
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001611 // First find top-most window that has asked to be on top of the
1612 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001613 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001614 int N = localmWindows.size();
1615 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001616 WindowState foundW = null;
1617 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001618 WindowState topCurW = null;
1619 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001620 int i = N;
1621 while (i > 0) {
1622 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001623 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001624 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1625 if (topCurW == null) {
1626 topCurW = w;
1627 topCurI = i;
1628 }
1629 continue;
1630 }
1631 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001632 if (w.mAppToken != null) {
1633 // If this window's app token is hidden and not animating,
1634 // it is of no interest to us.
1635 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001636 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001637 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001638 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001639 continue;
1640 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001641 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001642 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001643 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1644 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001645 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001646 && (mWallpaperTarget == w
1647 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001648 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001649 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001650 foundW = w;
1651 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001652 if (w == mWallpaperTarget && ((w.mAppToken != null
1653 && w.mAppToken.animation != null)
1654 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001655 // The current wallpaper target is animating, so we'll
1656 // look behind it for another possible target and figure
1657 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001658 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001659 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001660 continue;
1661 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001662 break;
1663 }
1664 }
1665
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001666 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001667 // If we are currently waiting for an app transition, and either
1668 // the current target or the next target are involved with it,
1669 // then hold off on doing anything with the wallpaper.
1670 // Note that we are checking here for just whether the target
1671 // is part of an app token... which is potentially overly aggressive
1672 // (the app token may not be involved in the transition), but good
1673 // enough (we'll just wait until whatever transition is pending
1674 // executes).
1675 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001677 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001678 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001679 }
1680 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001681 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001682 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001683 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001684 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001685 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001686
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001687 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001688 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001689 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001690 + " oldTarget: " + mWallpaperTarget);
1691 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001692
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001693 mLowerWallpaperTarget = null;
1694 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001695
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001696 WindowState oldW = mWallpaperTarget;
1697 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001698
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001699 // Now what is happening... if the current and new targets are
1700 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001701 if (foundW != null && oldW != null) {
1702 boolean oldAnim = oldW.mAnimation != null
1703 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1704 boolean foundAnim = foundW.mAnimation != null
1705 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001706 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001707 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001708 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001709 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001710 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001711 int oldI = localmWindows.indexOf(oldW);
1712 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001713 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001714 }
1715 if (oldI >= 0) {
1716 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001717 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001718 + "=" + oldW + "; new#" + foundI
1719 + "=" + foundW);
1720 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001721
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001722 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001723 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001724 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001725 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001726 }
1727 mWallpaperTarget = oldW;
1728 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001729
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001730 // Now set the upper and lower wallpaper targets
1731 // correctly, and make sure that we are positioning
1732 // the wallpaper below the lower.
1733 if (foundI > oldI) {
1734 // The new target is on top of the old one.
1735 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001736 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001737 }
1738 mUpperWallpaperTarget = foundW;
1739 mLowerWallpaperTarget = oldW;
1740 foundW = oldW;
1741 foundI = oldI;
1742 } else {
1743 // The new target is below the old one.
1744 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001745 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001746 }
1747 mUpperWallpaperTarget = oldW;
1748 mLowerWallpaperTarget = foundW;
1749 }
1750 }
1751 }
1752 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001753
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001754 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001755 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001756 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1757 || (mLowerWallpaperTarget.mAppToken != null
1758 && mLowerWallpaperTarget.mAppToken.animation != null);
1759 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1760 || (mUpperWallpaperTarget.mAppToken != null
1761 && mUpperWallpaperTarget.mAppToken.animation != null);
1762 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001763 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001764 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001765 }
1766 mLowerWallpaperTarget = null;
1767 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001768 }
1769 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001770
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001771 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001772 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001773 // The window is visible to the compositor... but is it visible
1774 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001775 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001776 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001777
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001778 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001779 // its layer adjustment. Only do this if we are not transfering
1780 // between two wallpaper targets.
1781 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001782 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001783 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001784
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001785 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1786 * TYPE_LAYER_MULTIPLIER
1787 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001788
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001789 // Now w is the window we are supposed to be behind... but we
1790 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001791 // AND any starting window associated with it, AND below the
1792 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001793 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001794 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001795 if (wb.mBaseLayer < maxLayer &&
1796 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001797 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001798 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001799 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001800 // This window is not related to the previous one in any
1801 // interesting way, so stop here.
1802 break;
1803 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001804 foundW = wb;
1805 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001806 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001807 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001808 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001809 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001810
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001811 if (foundW == null && topCurW != null) {
1812 // There is no wallpaper target, so it goes at the bottom.
1813 // We will assume it is the same place as last time, if known.
1814 foundW = topCurW;
1815 foundI = topCurI+1;
1816 } else {
1817 // Okay i is the position immediately above the wallpaper. Look at
1818 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001819 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001820 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001821
Dianne Hackborn284ac932009-08-28 10:34:25 -07001822 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001823 if (mWallpaperTarget.mWallpaperX >= 0) {
1824 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001825 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001826 }
1827 if (mWallpaperTarget.mWallpaperY >= 0) {
1828 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001829 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001830 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001831 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001832
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001833 // Start stepping backwards from here, ensuring that our wallpaper windows
1834 // are correctly placed.
1835 int curTokenIndex = mWallpaperTokens.size();
1836 while (curTokenIndex > 0) {
1837 curTokenIndex--;
1838 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001839 if (token.hidden == visible) {
1840 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1841 token.hidden = !visible;
1842 // Need to do a layout to ensure the wallpaper now has the
1843 // correct size.
1844 mLayoutNeeded = true;
1845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001846
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001847 int curWallpaperIndex = token.windows.size();
1848 while (curWallpaperIndex > 0) {
1849 curWallpaperIndex--;
1850 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001851
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001852 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001853 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001854 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001855
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001856 // First, make sure the client has the current visibility
1857 // state.
1858 if (wallpaper.mWallpaperVisible != visible) {
1859 wallpaper.mWallpaperVisible = visible;
1860 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001861 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001862 "Setting visibility of wallpaper " + wallpaper
1863 + ": " + visible);
1864 wallpaper.mClient.dispatchAppVisibility(visible);
1865 } catch (RemoteException e) {
1866 }
1867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001868
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001869 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001871 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001872
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001873 // First, if this window is at the current index, then all
1874 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001875 if (wallpaper == foundW) {
1876 foundI--;
1877 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001878 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001879 continue;
1880 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001881
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001882 // The window didn't match... the current wallpaper window,
1883 // wherever it is, is in the wrong place, so make sure it is
1884 // not in the list.
1885 int oldIndex = localmWindows.indexOf(wallpaper);
1886 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001887 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001888 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001889 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001890 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001891 if (oldIndex < foundI) {
1892 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001893 }
1894 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001895
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001896 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001897 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001898 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001899 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001900
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001901 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001902 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001903 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001904 }
1905 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001906
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001907 return changed;
1908 }
1909
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001910 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001911 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001912 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001913 mWallpaperAnimLayerAdjustment = adj;
1914 int curTokenIndex = mWallpaperTokens.size();
1915 while (curTokenIndex > 0) {
1916 curTokenIndex--;
1917 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1918 int curWallpaperIndex = token.windows.size();
1919 while (curWallpaperIndex > 0) {
1920 curWallpaperIndex--;
1921 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1922 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001923 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001924 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001925 }
1926 }
1927 }
1928
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001929 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1930 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001931 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001932 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001933 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001934 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001935 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1936 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1937 changed = wallpaperWin.mXOffset != offset;
1938 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001939 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001940 + wallpaperWin + " x: " + offset);
1941 wallpaperWin.mXOffset = offset;
1942 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001943 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001944 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001945 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001946 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001947 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001948
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001949 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001950 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001951 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1952 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1953 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001954 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001955 + wallpaperWin + " y: " + offset);
1956 changed = true;
1957 wallpaperWin.mYOffset = offset;
1958 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001959 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001960 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001961 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001962 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001963 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001964
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001965 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001966 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001967 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001968 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1969 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001970 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001971 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001972 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001973 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001974 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1975 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001976 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001977 if (mWaitingOnWallpaper != null) {
1978 long start = SystemClock.uptimeMillis();
1979 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1980 < start) {
1981 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001982 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001983 "Waiting for offset complete...");
1984 mWindowMap.wait(WALLPAPER_TIMEOUT);
1985 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001986 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001987 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001988 if ((start+WALLPAPER_TIMEOUT)
1989 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001990 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001991 + wallpaperWin);
1992 mLastWallpaperTimeoutTime = start;
1993 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001994 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001995 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001996 }
1997 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001998 } catch (RemoteException e) {
1999 }
2000 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002001
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002002 return changed;
2003 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002004
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002005 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002006 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002007 if (mWaitingOnWallpaper != null &&
2008 mWaitingOnWallpaper.mClient.asBinder() == window) {
2009 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002010 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002011 }
2012 }
2013 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002014
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002015 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002016 final int dw = mDisplay.getWidth();
2017 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002018
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002019 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002020
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002021 WindowState target = mWallpaperTarget;
2022 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002023 if (target.mWallpaperX >= 0) {
2024 mLastWallpaperX = target.mWallpaperX;
2025 } else if (changingTarget.mWallpaperX >= 0) {
2026 mLastWallpaperX = changingTarget.mWallpaperX;
2027 }
2028 if (target.mWallpaperY >= 0) {
2029 mLastWallpaperY = target.mWallpaperY;
2030 } else if (changingTarget.mWallpaperY >= 0) {
2031 mLastWallpaperY = changingTarget.mWallpaperY;
2032 }
2033 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002034
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002035 int curTokenIndex = mWallpaperTokens.size();
2036 while (curTokenIndex > 0) {
2037 curTokenIndex--;
2038 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2039 int curWallpaperIndex = token.windows.size();
2040 while (curWallpaperIndex > 0) {
2041 curWallpaperIndex--;
2042 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2043 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2044 wallpaper.computeShownFrameLocked();
2045 changed = true;
2046 // We only want to be synchronous with one wallpaper.
2047 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002048 }
2049 }
2050 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002051
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002052 return changed;
2053 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002054
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002055 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002056 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002057 final int dw = mDisplay.getWidth();
2058 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002059
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002060 int curTokenIndex = mWallpaperTokens.size();
2061 while (curTokenIndex > 0) {
2062 curTokenIndex--;
2063 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002064 if (token.hidden == visible) {
2065 token.hidden = !visible;
2066 // Need to do a layout to ensure the wallpaper now has the
2067 // correct size.
2068 mLayoutNeeded = true;
2069 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002070
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002071 int curWallpaperIndex = token.windows.size();
2072 while (curWallpaperIndex > 0) {
2073 curWallpaperIndex--;
2074 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2075 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002076 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002077 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002078
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002079 if (wallpaper.mWallpaperVisible != visible) {
2080 wallpaper.mWallpaperVisible = visible;
2081 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002082 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002083 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002084 + ": " + visible);
2085 wallpaper.mClient.dispatchAppVisibility(visible);
2086 } catch (RemoteException e) {
2087 }
2088 }
2089 }
2090 }
2091 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 public int addWindow(Session session, IWindow client,
2094 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002095 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002096 int res = mPolicy.checkAddPermission(attrs);
2097 if (res != WindowManagerImpl.ADD_OKAY) {
2098 return res;
2099 }
Romain Guy06882f82009-06-10 13:36:04 -07002100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 boolean reportNewConfig = false;
2102 WindowState attachedWindow = null;
2103 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002104 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002108 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 }
Romain Guy06882f82009-06-10 13:36:04 -07002110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002111 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002112 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002113 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2114 }
2115
2116 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002117 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002119 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 + attrs.token + ". Aborting.");
2121 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2122 }
2123 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2124 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002125 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 + attrs.token + ". Aborting.");
2127 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2128 }
2129 }
2130
2131 boolean addToken = false;
2132 WindowToken token = mTokenMap.get(attrs.token);
2133 if (token == null) {
2134 if (attrs.type >= FIRST_APPLICATION_WINDOW
2135 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002136 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 + attrs.token + ". Aborting.");
2138 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2139 }
2140 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002141 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 + attrs.token + ". Aborting.");
2143 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2144 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002145 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002146 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002147 + attrs.token + ". Aborting.");
2148 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 token = new WindowToken(attrs.token, -1, false);
2151 addToken = true;
2152 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2153 && attrs.type <= LAST_APPLICATION_WINDOW) {
2154 AppWindowToken atoken = token.appWindowToken;
2155 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002156 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 + token + ". Aborting.");
2158 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2159 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002160 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 + token + ". Aborting.");
2162 return WindowManagerImpl.ADD_APP_EXITING;
2163 }
2164 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2165 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002166 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2168 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2169 }
2170 } else if (attrs.type == TYPE_INPUT_METHOD) {
2171 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002172 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 + attrs.token + ". Aborting.");
2174 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2175 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002176 } else if (attrs.type == TYPE_WALLPAPER) {
2177 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002178 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002179 + attrs.token + ". Aborting.");
2180 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 }
2183
2184 win = new WindowState(session, client, token,
2185 attachedWindow, attrs, viewVisibility);
2186 if (win.mDeathRecipient == null) {
2187 // Client has apparently died, so there is no reason to
2188 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002189 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 + " that is dead, aborting.");
2191 return WindowManagerImpl.ADD_APP_EXITING;
2192 }
2193
2194 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 res = mPolicy.prepareAddWindowLw(win, attrs);
2197 if (res != WindowManagerImpl.ADD_OKAY) {
2198 return res;
2199 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002200
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002201 if (outInputChannel != null) {
2202 String name = win.makeInputChannelName();
2203 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2204 win.mInputChannel = inputChannels[0];
2205 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2206
2207 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209
2210 // From now on, no exceptions or errors allowed!
2211
2212 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002213
Dianne Hackborn5132b372010-07-29 12:51:35 -07002214 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002216 if (addToken) {
2217 mTokenMap.put(attrs.token, token);
2218 mTokenList.add(token);
2219 }
2220 win.attach();
2221 mWindowMap.put(client.asBinder(), win);
2222
2223 if (attrs.type == TYPE_APPLICATION_STARTING &&
2224 token.appWindowToken != null) {
2225 token.appWindowToken.startingWindow = win;
2226 }
2227
2228 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 if (attrs.type == TYPE_INPUT_METHOD) {
2231 mInputMethodWindow = win;
2232 addInputMethodWindowToListLocked(win);
2233 imMayMove = false;
2234 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2235 mInputMethodDialogs.add(win);
2236 addWindowToListInOrderLocked(win, true);
2237 adjustInputMethodDialogsLocked();
2238 imMayMove = false;
2239 } else {
2240 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002241 if (attrs.type == TYPE_WALLPAPER) {
2242 mLastWallpaperTimeoutTime = 0;
2243 adjustWallpaperWindowsLocked();
2244 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002245 adjustWallpaperWindowsLocked();
2246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247 }
Romain Guy06882f82009-06-10 13:36:04 -07002248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002251 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 if (mInTouchMode) {
2254 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2255 }
2256 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2257 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2258 }
Romain Guy06882f82009-06-10 13:36:04 -07002259
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002260 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002262 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2263 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 imMayMove = false;
2265 }
2266 }
Romain Guy06882f82009-06-10 13:36:04 -07002267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002269 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 }
Romain Guy06882f82009-06-10 13:36:04 -07002271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 assignLayersLocked();
2273 // Don't do layout here, the window must call
2274 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 //dump();
2277
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002278 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002279 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002280 }
Jeff Brown349703e2010-06-22 01:27:15 -07002281
Joe Onorato8a9b2202010-02-26 18:56:32 -08002282 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 TAG, "New client " + client.asBinder()
2284 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002285
2286 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2287 reportNewConfig = true;
2288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 }
2290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 if (reportNewConfig) {
2292 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 return res;
2298 }
Romain Guy06882f82009-06-10 13:36:04 -07002299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 public void removeWindow(Session session, IWindow client) {
2301 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002302 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 if (win == null) {
2304 return;
2305 }
2306 removeWindowLocked(session, win);
2307 }
2308 }
Romain Guy06882f82009-06-10 13:36:04 -07002309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 public void removeWindowLocked(Session session, WindowState win) {
2311
Joe Onorato8a9b2202010-02-26 18:56:32 -08002312 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 TAG, "Remove " + win + " client="
2314 + Integer.toHexString(System.identityHashCode(
2315 win.mClient.asBinder()))
2316 + ", surface=" + win.mSurface);
2317
2318 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002319
2320 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002321
Joe Onorato8a9b2202010-02-26 18:56:32 -08002322 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2324 + " mExiting=" + win.mExiting
2325 + " isAnimating=" + win.isAnimating()
2326 + " app-animation="
2327 + (win.mAppToken != null ? win.mAppToken.animation : null)
2328 + " inPendingTransaction="
2329 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2330 + " mDisplayFrozen=" + mDisplayFrozen);
2331 // Visibility of the removed window. Will be used later to update orientation later on.
2332 boolean wasVisible = false;
2333 // First, see if we need to run an animation. If we do, we have
2334 // to hold off on removing the window until the animation is done.
2335 // If the display is frozen, just remove immediately, since the
2336 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002337 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 // If we are not currently running the exit animation, we
2339 // need to see about starting one.
2340 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2343 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2344 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2345 }
2346 // Try starting an animation.
2347 if (applyAnimationLocked(win, transit, false)) {
2348 win.mExiting = true;
2349 }
2350 }
2351 if (win.mExiting || win.isAnimating()) {
2352 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002353 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 win.mExiting = true;
2355 win.mRemoveOnExit = true;
2356 mLayoutNeeded = true;
2357 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2358 performLayoutAndPlaceSurfacesLocked();
2359 if (win.mAppToken != null) {
2360 win.mAppToken.updateReportedVisibilityLocked();
2361 }
2362 //dump();
2363 Binder.restoreCallingIdentity(origId);
2364 return;
2365 }
2366 }
2367
2368 removeWindowInnerLocked(session, win);
2369 // Removing a visible window will effect the computed orientation
2370 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002371 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002372 != mForcedAppOrientation
2373 && updateOrientationFromAppTokensLocked()) {
2374 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2377 Binder.restoreCallingIdentity(origId);
2378 }
Romain Guy06882f82009-06-10 13:36:04 -07002379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 if (mInputMethodTarget == win) {
2384 moveInputMethodWindowsIfNeededLocked(false);
2385 }
Romain Guy06882f82009-06-10 13:36:04 -07002386
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002387 if (false) {
2388 RuntimeException e = new RuntimeException("here");
2389 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002390 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002391 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 mPolicy.removeWindowLw(win);
2394 win.removeLocked();
2395
2396 mWindowMap.remove(win.mClient.asBinder());
2397 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002398 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002399 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400
2401 if (mInputMethodWindow == win) {
2402 mInputMethodWindow = null;
2403 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2404 mInputMethodDialogs.remove(win);
2405 }
Romain Guy06882f82009-06-10 13:36:04 -07002406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 final WindowToken token = win.mToken;
2408 final AppWindowToken atoken = win.mAppToken;
2409 token.windows.remove(win);
2410 if (atoken != null) {
2411 atoken.allAppWindows.remove(win);
2412 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002413 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 TAG, "**** Removing window " + win + ": count="
2415 + token.windows.size());
2416 if (token.windows.size() == 0) {
2417 if (!token.explicit) {
2418 mTokenMap.remove(token.token);
2419 mTokenList.remove(token);
2420 } else if (atoken != null) {
2421 atoken.firstWindowDrawn = false;
2422 }
2423 }
2424
2425 if (atoken != null) {
2426 if (atoken.startingWindow == win) {
2427 atoken.startingWindow = null;
2428 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2429 // If this is the last window and we had requested a starting
2430 // transition window, well there is no point now.
2431 atoken.startingData = null;
2432 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2433 // If this is the last window except for a starting transition
2434 // window, we need to get rid of the starting transition.
2435 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002436 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 + ": no more real windows");
2438 }
2439 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2440 mH.sendMessage(m);
2441 }
2442 }
Romain Guy06882f82009-06-10 13:36:04 -07002443
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002444 if (win.mAttrs.type == TYPE_WALLPAPER) {
2445 mLastWallpaperTimeoutTime = 0;
2446 adjustWallpaperWindowsLocked();
2447 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002448 adjustWallpaperWindowsLocked();
2449 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 if (!mInLayout) {
2452 assignLayersLocked();
2453 mLayoutNeeded = true;
2454 performLayoutAndPlaceSurfacesLocked();
2455 if (win.mAppToken != null) {
2456 win.mAppToken.updateReportedVisibilityLocked();
2457 }
2458 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002459
2460 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 }
2462
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002463 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2464 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2465 + ": " + msg + " / " + w.mAttrs.getTitle();
2466 if (where != null) {
2467 Slog.i(TAG, str, where);
2468 } else {
2469 Slog.i(TAG, str);
2470 }
2471 }
2472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2474 long origId = Binder.clearCallingIdentity();
2475 try {
2476 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002477 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002479 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002480 Surface.openTransaction();
2481 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002482 if (SHOW_TRANSACTIONS) logSurface(w,
2483 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 w.mSurface.setTransparentRegionHint(region);
2485 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002486 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 Surface.closeTransaction();
2488 }
2489 }
2490 }
2491 } finally {
2492 Binder.restoreCallingIdentity(origId);
2493 }
2494 }
2495
2496 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002497 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 Rect visibleInsets) {
2499 long origId = Binder.clearCallingIdentity();
2500 try {
2501 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002502 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 if (w != null) {
2504 w.mGivenInsetsPending = false;
2505 w.mGivenContentInsets.set(contentInsets);
2506 w.mGivenVisibleInsets.set(visibleInsets);
2507 w.mTouchableInsets = touchableInsets;
2508 mLayoutNeeded = true;
2509 performLayoutAndPlaceSurfacesLocked();
2510 }
2511 }
2512 } finally {
2513 Binder.restoreCallingIdentity(origId);
2514 }
2515 }
Romain Guy06882f82009-06-10 13:36:04 -07002516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 public void getWindowDisplayFrame(Session session, IWindow client,
2518 Rect outDisplayFrame) {
2519 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002520 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002521 if (win == null) {
2522 outDisplayFrame.setEmpty();
2523 return;
2524 }
2525 outDisplayFrame.set(win.mDisplayFrame);
2526 }
2527 }
2528
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002529 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2530 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002531 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2532 window.mWallpaperX = x;
2533 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002534 window.mWallpaperXStep = xStep;
2535 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002536 if (updateWallpaperOffsetLocked(window, true)) {
2537 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002538 }
2539 }
2540 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002541
Dianne Hackborn75804932009-10-20 20:15:20 -07002542 void wallpaperCommandComplete(IBinder window, Bundle result) {
2543 synchronized (mWindowMap) {
2544 if (mWaitingOnWallpaper != null &&
2545 mWaitingOnWallpaper.mClient.asBinder() == window) {
2546 mWaitingOnWallpaper = null;
2547 mWindowMap.notifyAll();
2548 }
2549 }
2550 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002551
Dianne Hackborn75804932009-10-20 20:15:20 -07002552 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2553 String action, int x, int y, int z, Bundle extras, boolean sync) {
2554 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2555 || window == mUpperWallpaperTarget) {
2556 boolean doWait = sync;
2557 int curTokenIndex = mWallpaperTokens.size();
2558 while (curTokenIndex > 0) {
2559 curTokenIndex--;
2560 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2561 int curWallpaperIndex = token.windows.size();
2562 while (curWallpaperIndex > 0) {
2563 curWallpaperIndex--;
2564 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2565 try {
2566 wallpaper.mClient.dispatchWallpaperCommand(action,
2567 x, y, z, extras, sync);
2568 // We only want to be synchronous with one wallpaper.
2569 sync = false;
2570 } catch (RemoteException e) {
2571 }
2572 }
2573 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002574
Dianne Hackborn75804932009-10-20 20:15:20 -07002575 if (doWait) {
2576 // XXX Need to wait for result.
2577 }
2578 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002579
Dianne Hackborn75804932009-10-20 20:15:20 -07002580 return null;
2581 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 public int relayoutWindow(Session session, IWindow client,
2584 WindowManager.LayoutParams attrs, int requestedWidth,
2585 int requestedHeight, int viewVisibility, boolean insetsPending,
2586 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002587 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 boolean displayed = false;
2589 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002590 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002594 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 if (win == null) {
2596 return 0;
2597 }
2598 win.mRequestedWidth = requestedWidth;
2599 win.mRequestedHeight = requestedHeight;
2600
2601 if (attrs != null) {
2602 mPolicy.adjustWindowParamsLw(attrs);
2603 }
Romain Guy06882f82009-06-10 13:36:04 -07002604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 int attrChanges = 0;
2606 int flagChanges = 0;
2607 if (attrs != null) {
2608 flagChanges = win.mAttrs.flags ^= attrs.flags;
2609 attrChanges = win.mAttrs.copyFrom(attrs);
2610 }
2611
Joe Onorato8a9b2202010-02-26 18:56:32 -08002612 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613
2614 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2615 win.mAlpha = attrs.alpha;
2616 }
2617
2618 final boolean scaledWindow =
2619 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2620
2621 if (scaledWindow) {
2622 // requested{Width|Height} Surface's physical size
2623 // attrs.{width|height} Size on screen
2624 win.mHScale = (attrs.width != requestedWidth) ?
2625 (attrs.width / (float)requestedWidth) : 1.0f;
2626 win.mVScale = (attrs.height != requestedHeight) ?
2627 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002628 } else {
2629 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 }
2631
2632 boolean imMayMove = (flagChanges&(
2633 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2634 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 boolean focusMayChange = win.mViewVisibility != viewVisibility
2637 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2638 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002639
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002640 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2641 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 win.mRelayoutCalled = true;
2644 final int oldVisibility = win.mViewVisibility;
2645 win.mViewVisibility = viewVisibility;
2646 if (viewVisibility == View.VISIBLE &&
2647 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2648 displayed = !win.isVisibleLw();
2649 if (win.mExiting) {
2650 win.mExiting = false;
2651 win.mAnimation = null;
2652 }
2653 if (win.mDestroying) {
2654 win.mDestroying = false;
2655 mDestroySurface.remove(win);
2656 }
2657 if (oldVisibility == View.GONE) {
2658 win.mEnterAnimationPending = true;
2659 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002660 if (displayed) {
2661 if (win.mSurface != null && !win.mDrawPending
2662 && !win.mCommitDrawPending && !mDisplayFrozen
2663 && mPolicy.isScreenOn()) {
2664 applyEnterAnimationLocked(win);
2665 }
2666 if ((win.mAttrs.flags
2667 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2668 if (DEBUG_VISIBILITY) Slog.v(TAG,
2669 "Relayout window turning screen on: " + win);
2670 win.mTurnOnScreen = true;
2671 }
2672 int diff = 0;
2673 if (win.mConfiguration != mCurConfiguration
2674 && (win.mConfiguration == null
2675 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2676 win.mConfiguration = mCurConfiguration;
2677 if (DEBUG_CONFIGURATION) {
2678 Slog.i(TAG, "Window " + win + " visible with new config: "
2679 + win.mConfiguration + " / 0x"
2680 + Integer.toHexString(diff));
2681 }
2682 outConfig.setTo(mCurConfiguration);
2683 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2686 // To change the format, we need to re-build the surface.
2687 win.destroySurfaceLocked();
2688 displayed = true;
2689 }
2690 try {
2691 Surface surface = win.createSurfaceLocked();
2692 if (surface != null) {
2693 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002694 win.mReportDestroySurface = false;
2695 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002696 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002697 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002699 // For some reason there isn't a surface. Clear the
2700 // caller's object so they see the same state.
2701 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 }
2703 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002704 mInputMonitor.updateInputWindowsLw();
2705
Joe Onorato8a9b2202010-02-26 18:56:32 -08002706 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002707 + client + " (" + win.mAttrs.getTitle() + ")",
2708 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 Binder.restoreCallingIdentity(origId);
2710 return 0;
2711 }
2712 if (displayed) {
2713 focusMayChange = true;
2714 }
2715 if (win.mAttrs.type == TYPE_INPUT_METHOD
2716 && mInputMethodWindow == null) {
2717 mInputMethodWindow = win;
2718 imMayMove = true;
2719 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002720 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2721 && win.mAppToken != null
2722 && win.mAppToken.startingWindow != null) {
2723 // Special handling of starting window over the base
2724 // window of the app: propagate lock screen flags to it,
2725 // to provide the correct semantics while starting.
2726 final int mask =
2727 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002728 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2729 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002730 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2731 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 } else {
2734 win.mEnterAnimationPending = false;
2735 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002736 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002737 + ": mExiting=" + win.mExiting
2738 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 // If we are not currently running the exit animation, we
2740 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002741 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 // Try starting an animation; if there isn't one, we
2743 // can destroy the surface right away.
2744 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2745 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2746 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2747 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002748 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002750 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 } else if (win.isAnimating()) {
2753 // Currently in a hide animation... turn this into
2754 // an exit.
2755 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002756 } else if (win == mWallpaperTarget) {
2757 // If the wallpaper is currently behind this
2758 // window, we need to change both of them inside
2759 // of a transaction to avoid artifacts.
2760 win.mExiting = true;
2761 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 } else {
2763 if (mInputMethodWindow == win) {
2764 mInputMethodWindow = null;
2765 }
2766 win.destroySurfaceLocked();
2767 }
2768 }
2769 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002770
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002771 if (win.mSurface == null || (win.getAttrs().flags
2772 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2773 || win.mSurfacePendingDestroy) {
2774 // We are being called from a local process, which
2775 // means outSurface holds its current surface. Ensure the
2776 // surface object is cleared, but we don't want it actually
2777 // destroyed at this point.
2778 win.mSurfacePendingDestroy = false;
2779 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002780 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002781 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002782 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002783 "Keeping surface, will report destroy: " + win);
2784 win.mReportDestroySurface = true;
2785 outSurface.copyFrom(win.mSurface);
2786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002787 }
2788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 if (focusMayChange) {
2790 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2791 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 imMayMove = false;
2793 }
2794 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2795 }
Romain Guy06882f82009-06-10 13:36:04 -07002796
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002797 // updateFocusedWindowLocked() already assigned layers so we only need to
2798 // reassign them at this point if the IM window state gets shuffled
2799 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002801 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002802 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2803 // Little hack here -- we -should- be able to rely on the
2804 // function to return true if the IME has moved and needs
2805 // its layer recomputed. However, if the IME was hidden
2806 // and isn't actually moved in the list, its layer may be
2807 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 assignLayers = true;
2809 }
2810 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002811 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002812 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002813 assignLayers = true;
2814 }
2815 }
Romain Guy06882f82009-06-10 13:36:04 -07002816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 mLayoutNeeded = true;
2818 win.mGivenInsetsPending = insetsPending;
2819 if (assignLayers) {
2820 assignLayersLocked();
2821 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002822 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002824 if (displayed && win.mIsWallpaper) {
2825 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002826 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002828 if (win.mAppToken != null) {
2829 win.mAppToken.updateReportedVisibilityLocked();
2830 }
2831 outFrame.set(win.mFrame);
2832 outContentInsets.set(win.mContentInsets);
2833 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002834 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002836 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002837 + ", requestedHeight=" + requestedHeight
2838 + ", viewVisibility=" + viewVisibility
2839 + "\nRelayout returning frame=" + outFrame
2840 + ", surface=" + outSurface);
2841
Joe Onorato8a9b2202010-02-26 18:56:32 -08002842 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2844
2845 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002846
2847 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 }
2849
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002850 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 sendNewConfiguration();
2852 }
Romain Guy06882f82009-06-10 13:36:04 -07002853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2857 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2858 }
2859
2860 public void finishDrawingWindow(Session session, IWindow client) {
2861 final long origId = Binder.clearCallingIdentity();
2862 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002863 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002865 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2866 adjustWallpaperWindowsLocked();
2867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 mLayoutNeeded = true;
2869 performLayoutAndPlaceSurfacesLocked();
2870 }
2871 }
2872 Binder.restoreCallingIdentity(origId);
2873 }
2874
2875 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002876 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002877 + (lp != null ? lp.packageName : null)
2878 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2879 if (lp != null && lp.windowAnimations != 0) {
2880 // If this is a system resource, don't try to load it from the
2881 // application resources. It is nice to avoid loading application
2882 // resources if we can.
2883 String packageName = lp.packageName != null ? lp.packageName : "android";
2884 int resId = lp.windowAnimations;
2885 if ((resId&0xFF000000) == 0x01000000) {
2886 packageName = "android";
2887 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002888 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 + packageName);
2890 return AttributeCache.instance().get(packageName, resId,
2891 com.android.internal.R.styleable.WindowAnimation);
2892 }
2893 return null;
2894 }
Romain Guy06882f82009-06-10 13:36:04 -07002895
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002896 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002897 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002898 + packageName + " resId=0x" + Integer.toHexString(resId));
2899 if (packageName != null) {
2900 if ((resId&0xFF000000) == 0x01000000) {
2901 packageName = "android";
2902 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002903 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002904 + packageName);
2905 return AttributeCache.instance().get(packageName, resId,
2906 com.android.internal.R.styleable.WindowAnimation);
2907 }
2908 return null;
2909 }
2910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 private void applyEnterAnimationLocked(WindowState win) {
2912 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2913 if (win.mEnterAnimationPending) {
2914 win.mEnterAnimationPending = false;
2915 transit = WindowManagerPolicy.TRANSIT_ENTER;
2916 }
2917
2918 applyAnimationLocked(win, transit, true);
2919 }
2920
2921 private boolean applyAnimationLocked(WindowState win,
2922 int transit, boolean isEntrance) {
2923 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2924 // If we are trying to apply an animation, but already running
2925 // an animation of the same type, then just leave that one alone.
2926 return true;
2927 }
Romain Guy06882f82009-06-10 13:36:04 -07002928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 // Only apply an animation if the display isn't frozen. If it is
2930 // frozen, there is no reason to animate and it can cause strange
2931 // artifacts when we unfreeze the display if some different animation
2932 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002933 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 int anim = mPolicy.selectAnimationLw(win, transit);
2935 int attr = -1;
2936 Animation a = null;
2937 if (anim != 0) {
2938 a = AnimationUtils.loadAnimation(mContext, anim);
2939 } else {
2940 switch (transit) {
2941 case WindowManagerPolicy.TRANSIT_ENTER:
2942 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2943 break;
2944 case WindowManagerPolicy.TRANSIT_EXIT:
2945 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2946 break;
2947 case WindowManagerPolicy.TRANSIT_SHOW:
2948 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2949 break;
2950 case WindowManagerPolicy.TRANSIT_HIDE:
2951 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2952 break;
2953 }
2954 if (attr >= 0) {
2955 a = loadAnimation(win.mAttrs, attr);
2956 }
2957 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002958 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2960 + " mAnimation=" + win.mAnimation
2961 + " isEntrance=" + isEntrance);
2962 if (a != null) {
2963 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002964 RuntimeException e = null;
2965 if (!HIDE_STACK_CRAWLS) {
2966 e = new RuntimeException();
2967 e.fillInStackTrace();
2968 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002969 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 }
2971 win.setAnimation(a);
2972 win.mAnimationIsEntrance = isEntrance;
2973 }
2974 } else {
2975 win.clearAnimation();
2976 }
2977
2978 return win.mAnimation != null;
2979 }
2980
2981 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2982 int anim = 0;
2983 Context context = mContext;
2984 if (animAttr >= 0) {
2985 AttributeCache.Entry ent = getCachedAnimations(lp);
2986 if (ent != null) {
2987 context = ent.context;
2988 anim = ent.array.getResourceId(animAttr, 0);
2989 }
2990 }
2991 if (anim != 0) {
2992 return AnimationUtils.loadAnimation(context, anim);
2993 }
2994 return null;
2995 }
Romain Guy06882f82009-06-10 13:36:04 -07002996
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002997 private Animation loadAnimation(String packageName, int resId) {
2998 int anim = 0;
2999 Context context = mContext;
3000 if (resId >= 0) {
3001 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3002 if (ent != null) {
3003 context = ent.context;
3004 anim = resId;
3005 }
3006 }
3007 if (anim != 0) {
3008 return AnimationUtils.loadAnimation(context, anim);
3009 }
3010 return null;
3011 }
3012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013 private boolean applyAnimationLocked(AppWindowToken wtoken,
3014 WindowManager.LayoutParams lp, int transit, boolean enter) {
3015 // Only apply an animation if the display isn't frozen. If it is
3016 // frozen, there is no reason to animate and it can cause strange
3017 // artifacts when we unfreeze the display if some different animation
3018 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003019 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003020 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003021 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003022 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003023 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003024 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003025 } else if (mNextAppTransitionPackage != null) {
3026 a = loadAnimation(mNextAppTransitionPackage, enter ?
3027 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003028 } else {
3029 int animAttr = 0;
3030 switch (transit) {
3031 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3032 animAttr = enter
3033 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3034 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3035 break;
3036 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3037 animAttr = enter
3038 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3039 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3040 break;
3041 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3042 animAttr = enter
3043 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3044 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3045 break;
3046 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3047 animAttr = enter
3048 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3049 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3050 break;
3051 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3052 animAttr = enter
3053 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3054 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3055 break;
3056 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3057 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003058 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003059 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3060 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003061 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003062 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003063 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3064 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003065 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003066 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003067 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003068 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3069 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3070 break;
3071 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3072 animAttr = enter
3073 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3074 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3075 break;
3076 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3077 animAttr = enter
3078 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3079 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003080 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003081 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003082 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003083 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003084 + " anim=" + a
3085 + " animAttr=0x" + Integer.toHexString(animAttr)
3086 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 if (a != null) {
3089 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003090 RuntimeException e = null;
3091 if (!HIDE_STACK_CRAWLS) {
3092 e = new RuntimeException();
3093 e.fillInStackTrace();
3094 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003095 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003096 }
3097 wtoken.setAnimation(a);
3098 }
3099 } else {
3100 wtoken.clearAnimation();
3101 }
3102
3103 return wtoken.animation != null;
3104 }
3105
3106 // -------------------------------------------------------------
3107 // Application Window Tokens
3108 // -------------------------------------------------------------
3109
3110 public void validateAppTokens(List tokens) {
3111 int v = tokens.size()-1;
3112 int m = mAppTokens.size()-1;
3113 while (v >= 0 && m >= 0) {
3114 AppWindowToken wtoken = mAppTokens.get(m);
3115 if (wtoken.removed) {
3116 m--;
3117 continue;
3118 }
3119 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003120 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3122 }
3123 v--;
3124 m--;
3125 }
3126 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003127 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 v--;
3129 }
3130 while (m >= 0) {
3131 AppWindowToken wtoken = mAppTokens.get(m);
3132 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003133 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003134 }
3135 m--;
3136 }
3137 }
3138
3139 boolean checkCallingPermission(String permission, String func) {
3140 // Quick check: if the calling permission is me, it's all okay.
3141 if (Binder.getCallingPid() == Process.myPid()) {
3142 return true;
3143 }
Romain Guy06882f82009-06-10 13:36:04 -07003144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003145 if (mContext.checkCallingPermission(permission)
3146 == PackageManager.PERMISSION_GRANTED) {
3147 return true;
3148 }
3149 String msg = "Permission Denial: " + func + " from pid="
3150 + Binder.getCallingPid()
3151 + ", uid=" + Binder.getCallingUid()
3152 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003153 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 return false;
3155 }
Romain Guy06882f82009-06-10 13:36:04 -07003156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 AppWindowToken findAppWindowToken(IBinder token) {
3158 WindowToken wtoken = mTokenMap.get(token);
3159 if (wtoken == null) {
3160 return null;
3161 }
3162 return wtoken.appWindowToken;
3163 }
Romain Guy06882f82009-06-10 13:36:04 -07003164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003165 public void addWindowToken(IBinder token, int type) {
3166 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3167 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003168 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 }
Romain Guy06882f82009-06-10 13:36:04 -07003170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 synchronized(mWindowMap) {
3172 WindowToken wtoken = mTokenMap.get(token);
3173 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003174 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175 return;
3176 }
3177 wtoken = new WindowToken(token, type, true);
3178 mTokenMap.put(token, wtoken);
3179 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003180 if (type == TYPE_WALLPAPER) {
3181 mWallpaperTokens.add(wtoken);
3182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 }
3184 }
Romain Guy06882f82009-06-10 13:36:04 -07003185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 public void removeWindowToken(IBinder token) {
3187 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3188 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003189 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 }
3191
3192 final long origId = Binder.clearCallingIdentity();
3193 synchronized(mWindowMap) {
3194 WindowToken wtoken = mTokenMap.remove(token);
3195 mTokenList.remove(wtoken);
3196 if (wtoken != null) {
3197 boolean delayed = false;
3198 if (!wtoken.hidden) {
3199 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003201 final int N = wtoken.windows.size();
3202 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003204 for (int i=0; i<N; i++) {
3205 WindowState win = wtoken.windows.get(i);
3206
3207 if (win.isAnimating()) {
3208 delayed = true;
3209 }
Romain Guy06882f82009-06-10 13:36:04 -07003210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003211 if (win.isVisibleNow()) {
3212 applyAnimationLocked(win,
3213 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 changed = true;
3215 }
3216 }
3217
3218 if (changed) {
3219 mLayoutNeeded = true;
3220 performLayoutAndPlaceSurfacesLocked();
3221 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3222 }
Romain Guy06882f82009-06-10 13:36:04 -07003223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 if (delayed) {
3225 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003226 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3227 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003228 }
3229 }
Romain Guy06882f82009-06-10 13:36:04 -07003230
Jeff Brownc5ed5912010-07-14 18:48:53 -07003231 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003232 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003233 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234 }
3235 }
3236 Binder.restoreCallingIdentity(origId);
3237 }
3238
3239 public void addAppToken(int addPos, IApplicationToken token,
3240 int groupId, int requestedOrientation, boolean fullscreen) {
3241 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3242 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003243 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003244 }
Jeff Brown349703e2010-06-22 01:27:15 -07003245
3246 // Get the dispatching timeout here while we are not holding any locks so that it
3247 // can be cached by the AppWindowToken. The timeout value is used later by the
3248 // input dispatcher in code that does hold locks. If we did not cache the value
3249 // here we would run the chance of introducing a deadlock between the window manager
3250 // (which holds locks while updating the input dispatcher state) and the activity manager
3251 // (which holds locks while querying the application token).
3252 long inputDispatchingTimeoutNanos;
3253 try {
3254 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3255 } catch (RemoteException ex) {
3256 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3257 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3258 }
Romain Guy06882f82009-06-10 13:36:04 -07003259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 synchronized(mWindowMap) {
3261 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3262 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003263 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 return;
3265 }
3266 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003267 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 wtoken.groupId = groupId;
3269 wtoken.appFullscreen = fullscreen;
3270 wtoken.requestedOrientation = requestedOrientation;
3271 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003272 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 mTokenMap.put(token.asBinder(), wtoken);
3274 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003276 // Application tokens start out hidden.
3277 wtoken.hidden = true;
3278 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 //dump();
3281 }
3282 }
Romain Guy06882f82009-06-10 13:36:04 -07003283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 public void setAppGroupId(IBinder token, int groupId) {
3285 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3286 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003287 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288 }
3289
3290 synchronized(mWindowMap) {
3291 AppWindowToken wtoken = findAppWindowToken(token);
3292 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003293 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 return;
3295 }
3296 wtoken.groupId = groupId;
3297 }
3298 }
Romain Guy06882f82009-06-10 13:36:04 -07003299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003300 public int getOrientationFromWindowsLocked() {
3301 int pos = mWindows.size() - 1;
3302 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003303 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304 pos--;
3305 if (wtoken.mAppToken != null) {
3306 // We hit an application window. so the orientation will be determined by the
3307 // app window. No point in continuing further.
3308 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3309 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003310 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 continue;
3312 }
3313 int req = wtoken.mAttrs.screenOrientation;
3314 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3315 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3316 continue;
3317 } else {
3318 return req;
3319 }
3320 }
3321 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3322 }
Romain Guy06882f82009-06-10 13:36:04 -07003323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003325 int pos = mAppTokens.size() - 1;
3326 int curGroup = 0;
3327 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3328 boolean findingBehind = false;
3329 boolean haveGroup = false;
3330 boolean lastFullscreen = false;
3331 while (pos >= 0) {
3332 AppWindowToken wtoken = mAppTokens.get(pos);
3333 pos--;
3334 // if we're about to tear down this window and not seek for
3335 // the behind activity, don't use it for orientation
3336 if (!findingBehind
3337 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3338 continue;
3339 }
3340
3341 if (!haveGroup) {
3342 // We ignore any hidden applications on the top.
3343 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003344 continue;
3345 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003346 haveGroup = true;
3347 curGroup = wtoken.groupId;
3348 lastOrientation = wtoken.requestedOrientation;
3349 } else if (curGroup != wtoken.groupId) {
3350 // If we have hit a new application group, and the bottom
3351 // of the previous group didn't explicitly say to use
3352 // the orientation behind it, and the last app was
3353 // full screen, then we'll stick with the
3354 // user's orientation.
3355 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3356 && lastFullscreen) {
3357 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003359 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003360 int or = wtoken.requestedOrientation;
3361 // If this application is fullscreen, and didn't explicitly say
3362 // to use the orientation behind it, then just take whatever
3363 // orientation it has and ignores whatever is under it.
3364 lastFullscreen = wtoken.appFullscreen;
3365 if (lastFullscreen
3366 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3367 return or;
3368 }
3369 // If this application has requested an explicit orientation,
3370 // then use it.
3371 if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
3372 or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
3373 or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
3374 or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
3375 or == ActivityInfo.SCREEN_ORIENTATION_USER) {
3376 return or;
3377 }
3378 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3379 }
3380 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
Romain Guy06882f82009-06-10 13:36:04 -07003382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003384 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003385 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3386 "updateOrientationFromAppTokens()")) {
3387 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3388 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003389
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003390 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003391 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003392
3393 synchronized(mWindowMap) {
3394 if (updateOrientationFromAppTokensLocked()) {
3395 if (freezeThisOneIfNeeded != null) {
3396 AppWindowToken wtoken = findAppWindowToken(
3397 freezeThisOneIfNeeded);
3398 if (wtoken != null) {
3399 startAppFreezingScreenLocked(wtoken,
3400 ActivityInfo.CONFIG_ORIENTATION);
3401 }
3402 }
3403 config = computeNewConfigurationLocked();
3404
3405 } else if (currentConfig != null) {
3406 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003407 // state mismatches the activity manager's, update it,
3408 // disregarding font scale, which should remain set to
3409 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003410 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003411 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003412 if (computeNewConfigurationLocked(mTempConfiguration)) {
3413 if (currentConfig.diff(mTempConfiguration) != 0) {
3414 mWaitingForConfig = true;
3415 mLayoutNeeded = true;
3416 startFreezingDisplayLocked();
3417 config = new Configuration(mTempConfiguration);
3418 }
3419 }
3420 }
3421 }
3422
Dianne Hackborncfaef692009-06-15 14:24:44 -07003423 Binder.restoreCallingIdentity(ident);
3424 return config;
3425 }
3426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003427 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003428 * Determine the new desired orientation of the display, returning
3429 * a non-null new Configuration if it has changed from the current
3430 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3431 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3432 * SCREEN. This will typically be done for you if you call
3433 * sendNewConfiguration().
3434 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 * The orientation is computed from non-application windows first. If none of
3436 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003437 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003438 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3439 * android.os.IBinder)
3440 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003441 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003442 if (mDisplayFrozen) {
3443 // If the display is frozen, some activities may be in the middle
3444 // of restarting, and thus have removed their old window. If the
3445 // window has the flag to hide the lock screen, then the lock screen
3446 // can re-appear and inflict its own orientation on us. Keep the
3447 // orientation stable until this all settles down.
3448 return false;
3449 }
3450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 long ident = Binder.clearCallingIdentity();
3453 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003454 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003457 mForcedAppOrientation = req;
3458 //send a message to Policy indicating orientation change to take
3459 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003460 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003461 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3462 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3463 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 }
3465 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003466
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003467 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003468 } finally {
3469 Binder.restoreCallingIdentity(ident);
3470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 }
Romain Guy06882f82009-06-10 13:36:04 -07003472
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003473 int computeForcedAppOrientationLocked() {
3474 int req = getOrientationFromWindowsLocked();
3475 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3476 req = getOrientationFromAppTokensLocked();
3477 }
3478 return req;
3479 }
Romain Guy06882f82009-06-10 13:36:04 -07003480
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003481 public void setNewConfiguration(Configuration config) {
3482 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3483 "setNewConfiguration()")) {
3484 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3485 }
3486
3487 synchronized(mWindowMap) {
3488 mCurConfiguration = new Configuration(config);
3489 mWaitingForConfig = false;
3490 performLayoutAndPlaceSurfacesLocked();
3491 }
3492 }
3493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3495 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3496 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003497 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 }
Romain Guy06882f82009-06-10 13:36:04 -07003499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 synchronized(mWindowMap) {
3501 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3502 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003503 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 return;
3505 }
Romain Guy06882f82009-06-10 13:36:04 -07003506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 wtoken.requestedOrientation = requestedOrientation;
3508 }
3509 }
Romain Guy06882f82009-06-10 13:36:04 -07003510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 public int getAppOrientation(IApplicationToken token) {
3512 synchronized(mWindowMap) {
3513 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3514 if (wtoken == null) {
3515 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3516 }
Romain Guy06882f82009-06-10 13:36:04 -07003517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 return wtoken.requestedOrientation;
3519 }
3520 }
Romain Guy06882f82009-06-10 13:36:04 -07003521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3523 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3524 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003525 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 }
3527
3528 synchronized(mWindowMap) {
3529 boolean changed = false;
3530 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003531 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 changed = mFocusedApp != null;
3533 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003534 if (changed) {
3535 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 } else {
3538 AppWindowToken newFocus = findAppWindowToken(token);
3539 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003540 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 return;
3542 }
3543 changed = mFocusedApp != newFocus;
3544 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003545 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003546 if (changed) {
3547 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 }
3550
3551 if (moveFocusNow && changed) {
3552 final long origId = Binder.clearCallingIdentity();
3553 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3554 Binder.restoreCallingIdentity(origId);
3555 }
3556 }
3557 }
3558
3559 public void prepareAppTransition(int transit) {
3560 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3561 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003562 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 }
Romain Guy06882f82009-06-10 13:36:04 -07003564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003566 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 TAG, "Prepare app transition: transit=" + transit
3568 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003569 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003570 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3571 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003573 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3574 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3575 // Opening a new task always supersedes a close for the anim.
3576 mNextAppTransition = transit;
3577 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3578 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3579 // Opening a new activity always supersedes a close for the anim.
3580 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 }
3582 mAppTransitionReady = false;
3583 mAppTransitionTimeout = false;
3584 mStartingIconInTransition = false;
3585 mSkipAppTransitionAnimation = false;
3586 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3587 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3588 5000);
3589 }
3590 }
3591 }
3592
3593 public int getPendingAppTransition() {
3594 return mNextAppTransition;
3595 }
Romain Guy06882f82009-06-10 13:36:04 -07003596
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003597 public void overridePendingAppTransition(String packageName,
3598 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003599 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003600 mNextAppTransitionPackage = packageName;
3601 mNextAppTransitionEnter = enterAnim;
3602 mNextAppTransitionExit = exitAnim;
3603 }
3604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 public void executeAppTransition() {
3607 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3608 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003609 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 }
Romain Guy06882f82009-06-10 13:36:04 -07003611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003613 if (DEBUG_APP_TRANSITIONS) {
3614 RuntimeException e = new RuntimeException("here");
3615 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003616 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003617 + mNextAppTransition, e);
3618 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003619 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 mAppTransitionReady = true;
3621 final long origId = Binder.clearCallingIdentity();
3622 performLayoutAndPlaceSurfacesLocked();
3623 Binder.restoreCallingIdentity(origId);
3624 }
3625 }
3626 }
3627
3628 public void setAppStartingWindow(IBinder token, String pkg,
3629 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3630 IBinder transferFrom, boolean createIfNeeded) {
3631 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3632 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003633 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 }
3635
3636 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003637 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3639 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 AppWindowToken wtoken = findAppWindowToken(token);
3642 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 return;
3645 }
3646
3647 // If the display is frozen, we won't do anything until the
3648 // actual window is displayed so there is no reason to put in
3649 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003650 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003651 return;
3652 }
Romain Guy06882f82009-06-10 13:36:04 -07003653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 if (wtoken.startingData != null) {
3655 return;
3656 }
Romain Guy06882f82009-06-10 13:36:04 -07003657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 if (transferFrom != null) {
3659 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3660 if (ttoken != null) {
3661 WindowState startingWindow = ttoken.startingWindow;
3662 if (startingWindow != null) {
3663 if (mStartingIconInTransition) {
3664 // In this case, the starting icon has already
3665 // been displayed, so start letting windows get
3666 // shown immediately without any more transitions.
3667 mSkipAppTransitionAnimation = true;
3668 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003669 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 "Moving existing starting from " + ttoken
3671 + " to " + wtoken);
3672 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003674 // Transfer the starting window over to the new
3675 // token.
3676 wtoken.startingData = ttoken.startingData;
3677 wtoken.startingView = ttoken.startingView;
3678 wtoken.startingWindow = startingWindow;
3679 ttoken.startingData = null;
3680 ttoken.startingView = null;
3681 ttoken.startingWindow = null;
3682 ttoken.startingMoved = true;
3683 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003684 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003686 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003687 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003689 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 ttoken.windows.remove(startingWindow);
3691 ttoken.allAppWindows.remove(startingWindow);
3692 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 // Propagate other interesting state between the
3695 // tokens. If the old token is displayed, we should
3696 // immediately force the new one to be displayed. If
3697 // it is animating, we need to move that animation to
3698 // the new one.
3699 if (ttoken.allDrawn) {
3700 wtoken.allDrawn = true;
3701 }
3702 if (ttoken.firstWindowDrawn) {
3703 wtoken.firstWindowDrawn = true;
3704 }
3705 if (!ttoken.hidden) {
3706 wtoken.hidden = false;
3707 wtoken.hiddenRequested = false;
3708 wtoken.willBeHidden = false;
3709 }
3710 if (wtoken.clientHidden != ttoken.clientHidden) {
3711 wtoken.clientHidden = ttoken.clientHidden;
3712 wtoken.sendAppVisibilityToClients();
3713 }
3714 if (ttoken.animation != null) {
3715 wtoken.animation = ttoken.animation;
3716 wtoken.animating = ttoken.animating;
3717 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3718 ttoken.animation = null;
3719 ttoken.animLayerAdjustment = 0;
3720 wtoken.updateLayers();
3721 ttoken.updateLayers();
3722 }
Romain Guy06882f82009-06-10 13:36:04 -07003723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 mLayoutNeeded = true;
3726 performLayoutAndPlaceSurfacesLocked();
3727 Binder.restoreCallingIdentity(origId);
3728 return;
3729 } else if (ttoken.startingData != null) {
3730 // The previous app was getting ready to show a
3731 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003732 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 "Moving pending starting from " + ttoken
3734 + " to " + wtoken);
3735 wtoken.startingData = ttoken.startingData;
3736 ttoken.startingData = null;
3737 ttoken.startingMoved = true;
3738 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3739 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3740 // want to process the message ASAP, before any other queued
3741 // messages.
3742 mH.sendMessageAtFrontOfQueue(m);
3743 return;
3744 }
3745 }
3746 }
3747
3748 // There is no existing starting window, and the caller doesn't
3749 // want us to create one, so that's it!
3750 if (!createIfNeeded) {
3751 return;
3752 }
Romain Guy06882f82009-06-10 13:36:04 -07003753
Dianne Hackborn284ac932009-08-28 10:34:25 -07003754 // If this is a translucent or wallpaper window, then don't
3755 // show a starting window -- the current effect (a full-screen
3756 // opaque starting window that fades away to the real contents
3757 // when it is ready) does not work for this.
3758 if (theme != 0) {
3759 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3760 com.android.internal.R.styleable.Window);
3761 if (ent.array.getBoolean(
3762 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3763 return;
3764 }
3765 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003766 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3767 return;
3768 }
3769 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003770 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3771 return;
3772 }
3773 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003775 mStartingIconInTransition = true;
3776 wtoken.startingData = new StartingData(
3777 pkg, theme, nonLocalizedLabel,
3778 labelRes, icon);
3779 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3780 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3781 // want to process the message ASAP, before any other queued
3782 // messages.
3783 mH.sendMessageAtFrontOfQueue(m);
3784 }
3785 }
3786
3787 public void setAppWillBeHidden(IBinder token) {
3788 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3789 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003790 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 }
3792
3793 AppWindowToken wtoken;
3794
3795 synchronized(mWindowMap) {
3796 wtoken = findAppWindowToken(token);
3797 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003798 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 -08003799 return;
3800 }
3801 wtoken.willBeHidden = true;
3802 }
3803 }
Romain Guy06882f82009-06-10 13:36:04 -07003804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3806 boolean visible, int transit, boolean performLayout) {
3807 boolean delayed = false;
3808
3809 if (wtoken.clientHidden == visible) {
3810 wtoken.clientHidden = !visible;
3811 wtoken.sendAppVisibilityToClients();
3812 }
Romain Guy06882f82009-06-10 13:36:04 -07003813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 wtoken.willBeHidden = false;
3815 if (wtoken.hidden == visible) {
3816 final int N = wtoken.allAppWindows.size();
3817 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003818 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3820 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003823
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003824 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 if (wtoken.animation == sDummyAnimation) {
3826 wtoken.animation = null;
3827 }
3828 applyAnimationLocked(wtoken, lp, transit, visible);
3829 changed = true;
3830 if (wtoken.animation != null) {
3831 delayed = runningAppAnimation = true;
3832 }
3833 }
Romain Guy06882f82009-06-10 13:36:04 -07003834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 for (int i=0; i<N; i++) {
3836 WindowState win = wtoken.allAppWindows.get(i);
3837 if (win == wtoken.startingWindow) {
3838 continue;
3839 }
3840
3841 if (win.isAnimating()) {
3842 delayed = true;
3843 }
Romain Guy06882f82009-06-10 13:36:04 -07003844
Joe Onorato8a9b2202010-02-26 18:56:32 -08003845 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 //win.dump(" ");
3847 if (visible) {
3848 if (!win.isVisibleNow()) {
3849 if (!runningAppAnimation) {
3850 applyAnimationLocked(win,
3851 WindowManagerPolicy.TRANSIT_ENTER, true);
3852 }
3853 changed = true;
3854 }
3855 } else if (win.isVisibleNow()) {
3856 if (!runningAppAnimation) {
3857 applyAnimationLocked(win,
3858 WindowManagerPolicy.TRANSIT_EXIT, false);
3859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 changed = true;
3861 }
3862 }
3863
3864 wtoken.hidden = wtoken.hiddenRequested = !visible;
3865 if (!visible) {
3866 unsetAppFreezingScreenLocked(wtoken, true, true);
3867 } else {
3868 // If we are being set visible, and the starting window is
3869 // not yet displayed, then make sure it doesn't get displayed.
3870 WindowState swin = wtoken.startingWindow;
3871 if (swin != null && (swin.mDrawPending
3872 || swin.mCommitDrawPending)) {
3873 swin.mPolicyVisibility = false;
3874 swin.mPolicyVisibilityAfterAnim = false;
3875 }
3876 }
Romain Guy06882f82009-06-10 13:36:04 -07003877
Joe Onorato8a9b2202010-02-26 18:56:32 -08003878 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3880 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003881
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003882 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003883 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003884 if (performLayout) {
3885 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3886 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07003887 } else {
3888 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 }
3891 }
3892
3893 if (wtoken.animation != null) {
3894 delayed = true;
3895 }
Romain Guy06882f82009-06-10 13:36:04 -07003896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 return delayed;
3898 }
3899
3900 public void setAppVisibility(IBinder token, boolean visible) {
3901 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3902 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003903 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
3905
3906 AppWindowToken wtoken;
3907
3908 synchronized(mWindowMap) {
3909 wtoken = findAppWindowToken(token);
3910 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003911 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 return;
3913 }
3914
3915 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003916 RuntimeException e = null;
3917 if (!HIDE_STACK_CRAWLS) {
3918 e = new RuntimeException();
3919 e.fillInStackTrace();
3920 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003921 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 + "): mNextAppTransition=" + mNextAppTransition
3923 + " hidden=" + wtoken.hidden
3924 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3925 }
Romain Guy06882f82009-06-10 13:36:04 -07003926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 // If we are preparing an app transition, then delay changing
3928 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003929 if (!mDisplayFrozen && mPolicy.isScreenOn()
3930 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 // Already in requested state, don't do anything more.
3932 if (wtoken.hiddenRequested != visible) {
3933 return;
3934 }
3935 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003936
Joe Onorato8a9b2202010-02-26 18:56:32 -08003937 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 TAG, "Setting dummy animation on: " + wtoken);
3939 wtoken.setDummyAnimation();
3940 mOpeningApps.remove(wtoken);
3941 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003942 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 wtoken.inPendingTransaction = true;
3944 if (visible) {
3945 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 wtoken.startingDisplayed = false;
3947 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003948
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003949 // If the token is currently hidden (should be the
3950 // common case), then we need to set up to wait for
3951 // its windows to be ready.
3952 if (wtoken.hidden) {
3953 wtoken.allDrawn = false;
3954 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003955
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003956 if (wtoken.clientHidden) {
3957 // In the case where we are making an app visible
3958 // but holding off for a transition, we still need
3959 // to tell the client to make its windows visible so
3960 // they get drawn. Otherwise, we will wait on
3961 // performing the transition until all windows have
3962 // been drawn, they never will be, and we are sad.
3963 wtoken.clientHidden = false;
3964 wtoken.sendAppVisibilityToClients();
3965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 }
3967 } else {
3968 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003969
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003970 // If the token is currently visible (should be the
3971 // common case), then set up to wait for it to be hidden.
3972 if (!wtoken.hidden) {
3973 wtoken.waitingToHide = true;
3974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 }
3976 return;
3977 }
Romain Guy06882f82009-06-10 13:36:04 -07003978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003980 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 wtoken.updateReportedVisibilityLocked();
3982 Binder.restoreCallingIdentity(origId);
3983 }
3984 }
3985
3986 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3987 boolean unfreezeSurfaceNow, boolean force) {
3988 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003989 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 + " force=" + force);
3991 final int N = wtoken.allAppWindows.size();
3992 boolean unfrozeWindows = false;
3993 for (int i=0; i<N; i++) {
3994 WindowState w = wtoken.allAppWindows.get(i);
3995 if (w.mAppFreezing) {
3996 w.mAppFreezing = false;
3997 if (w.mSurface != null && !w.mOrientationChanging) {
3998 w.mOrientationChanging = true;
3999 }
4000 unfrozeWindows = true;
4001 }
4002 }
4003 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004004 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 wtoken.freezingScreen = false;
4006 mAppsFreezingScreen--;
4007 }
4008 if (unfreezeSurfaceNow) {
4009 if (unfrozeWindows) {
4010 mLayoutNeeded = true;
4011 performLayoutAndPlaceSurfacesLocked();
4012 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004013 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004014 }
4015 }
4016 }
Romain Guy06882f82009-06-10 13:36:04 -07004017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4019 int configChanges) {
4020 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004021 RuntimeException e = null;
4022 if (!HIDE_STACK_CRAWLS) {
4023 e = new RuntimeException();
4024 e.fillInStackTrace();
4025 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004026 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 + ": hidden=" + wtoken.hidden + " freezing="
4028 + wtoken.freezingScreen, e);
4029 }
4030 if (!wtoken.hiddenRequested) {
4031 if (!wtoken.freezingScreen) {
4032 wtoken.freezingScreen = true;
4033 mAppsFreezingScreen++;
4034 if (mAppsFreezingScreen == 1) {
4035 startFreezingDisplayLocked();
4036 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4037 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4038 5000);
4039 }
4040 }
4041 final int N = wtoken.allAppWindows.size();
4042 for (int i=0; i<N; i++) {
4043 WindowState w = wtoken.allAppWindows.get(i);
4044 w.mAppFreezing = true;
4045 }
4046 }
4047 }
Romain Guy06882f82009-06-10 13:36:04 -07004048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 public void startAppFreezingScreen(IBinder token, int configChanges) {
4050 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4051 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004052 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 }
4054
4055 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004056 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004057 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 return;
4059 }
Romain Guy06882f82009-06-10 13:36:04 -07004060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 AppWindowToken wtoken = findAppWindowToken(token);
4062 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004063 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 return;
4065 }
4066 final long origId = Binder.clearCallingIdentity();
4067 startAppFreezingScreenLocked(wtoken, configChanges);
4068 Binder.restoreCallingIdentity(origId);
4069 }
4070 }
Romain Guy06882f82009-06-10 13:36:04 -07004071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 public void stopAppFreezingScreen(IBinder token, boolean force) {
4073 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4074 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004075 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 }
4077
4078 synchronized(mWindowMap) {
4079 AppWindowToken wtoken = findAppWindowToken(token);
4080 if (wtoken == null || wtoken.appToken == null) {
4081 return;
4082 }
4083 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004084 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4086 unsetAppFreezingScreenLocked(wtoken, true, force);
4087 Binder.restoreCallingIdentity(origId);
4088 }
4089 }
Romain Guy06882f82009-06-10 13:36:04 -07004090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 public void removeAppToken(IBinder token) {
4092 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4093 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004094 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 }
4096
4097 AppWindowToken wtoken = null;
4098 AppWindowToken startingToken = null;
4099 boolean delayed = false;
4100
4101 final long origId = Binder.clearCallingIdentity();
4102 synchronized(mWindowMap) {
4103 WindowToken basewtoken = mTokenMap.remove(token);
4104 mTokenList.remove(basewtoken);
4105 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004106 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004107 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 wtoken.inPendingTransaction = false;
4109 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004110 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 if (mClosingApps.contains(wtoken)) {
4112 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004113 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004115 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 delayed = true;
4117 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004118 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 TAG, "Removing app " + wtoken + " delayed=" + delayed
4120 + " animation=" + wtoken.animation
4121 + " animating=" + wtoken.animating);
4122 if (delayed) {
4123 // set the token aside because it has an active animation to be finished
4124 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004125 } else {
4126 // Make sure there is no animation running on this token,
4127 // so any windows associated with it will be removed as
4128 // soon as their animations are complete
4129 wtoken.animation = null;
4130 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004131 }
4132 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004133 if (mLastEnterAnimToken == wtoken) {
4134 mLastEnterAnimToken = null;
4135 mLastEnterAnimParams = null;
4136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 wtoken.removed = true;
4138 if (wtoken.startingData != null) {
4139 startingToken = wtoken;
4140 }
4141 unsetAppFreezingScreenLocked(wtoken, true, true);
4142 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004143 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 mFocusedApp = null;
4145 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004146 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 }
4148 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004149 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 }
Romain Guy06882f82009-06-10 13:36:04 -07004151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 if (!delayed && wtoken != null) {
4153 wtoken.updateReportedVisibilityLocked();
4154 }
4155 }
4156 Binder.restoreCallingIdentity(origId);
4157
4158 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004159 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004160 + startingToken + ": app token removed");
4161 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4162 mH.sendMessage(m);
4163 }
4164 }
4165
4166 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4167 final int NW = token.windows.size();
4168 for (int i=0; i<NW; i++) {
4169 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004170 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004172 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 int j = win.mChildWindows.size();
4174 while (j > 0) {
4175 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004176 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004177 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004178 "Tmp removing child window " + cwin);
4179 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 }
4181 }
4182 return NW > 0;
4183 }
4184
4185 void dumpAppTokensLocked() {
4186 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004187 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004188 }
4189 }
Romain Guy06882f82009-06-10 13:36:04 -07004190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 void dumpWindowsLocked() {
4192 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004193 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 }
4195 }
Romain Guy06882f82009-06-10 13:36:04 -07004196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 private int findWindowOffsetLocked(int tokenPos) {
4198 final int NW = mWindows.size();
4199
4200 if (tokenPos >= mAppTokens.size()) {
4201 int i = NW;
4202 while (i > 0) {
4203 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004204 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004205 if (win.getAppToken() != null) {
4206 return i+1;
4207 }
4208 }
4209 }
4210
4211 while (tokenPos > 0) {
4212 // Find the first app token below the new position that has
4213 // a window displayed.
4214 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004215 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004217 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004218 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004219 "Skipping token -- currently sending to bottom");
4220 tokenPos--;
4221 continue;
4222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 int i = wtoken.windows.size();
4224 while (i > 0) {
4225 i--;
4226 WindowState win = wtoken.windows.get(i);
4227 int j = win.mChildWindows.size();
4228 while (j > 0) {
4229 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004230 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004231 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004232 for (int pos=NW-1; pos>=0; pos--) {
4233 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004234 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004235 "Found child win @" + (pos+1));
4236 return pos+1;
4237 }
4238 }
4239 }
4240 }
4241 for (int pos=NW-1; pos>=0; pos--) {
4242 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004243 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 return pos+1;
4245 }
4246 }
4247 }
4248 tokenPos--;
4249 }
4250
4251 return 0;
4252 }
4253
4254 private final int reAddWindowLocked(int index, WindowState win) {
4255 final int NCW = win.mChildWindows.size();
4256 boolean added = false;
4257 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004258 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004260 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004261 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 mWindows.add(index, win);
4263 index++;
4264 added = true;
4265 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004266 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004267 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 mWindows.add(index, cwin);
4269 index++;
4270 }
4271 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004272 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004273 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 mWindows.add(index, win);
4275 index++;
4276 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004277 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 return index;
4279 }
Romain Guy06882f82009-06-10 13:36:04 -07004280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4282 final int NW = token.windows.size();
4283 for (int i=0; i<NW; i++) {
4284 index = reAddWindowLocked(index, token.windows.get(i));
4285 }
4286 return index;
4287 }
4288
4289 public void moveAppToken(int index, IBinder token) {
4290 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4291 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004292 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 }
4294
4295 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004296 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 if (DEBUG_REORDER) dumpAppTokensLocked();
4298 final AppWindowToken wtoken = findAppWindowToken(token);
4299 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004300 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 + token + " (" + wtoken + ")");
4302 return;
4303 }
4304 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004305 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004309 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004310 if (DEBUG_REORDER) dumpWindowsLocked();
4311 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004312 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 if (DEBUG_REORDER) dumpWindowsLocked();
4314 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004315 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 if (DEBUG_REORDER) dumpWindowsLocked();
4317 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 mLayoutNeeded = true;
4319 performLayoutAndPlaceSurfacesLocked();
4320 }
4321 Binder.restoreCallingIdentity(origId);
4322 }
4323 }
4324
4325 private void removeAppTokensLocked(List<IBinder> tokens) {
4326 // XXX This should be done more efficiently!
4327 // (take advantage of the fact that both lists should be
4328 // ordered in the same way.)
4329 int N = tokens.size();
4330 for (int i=0; i<N; i++) {
4331 IBinder token = tokens.get(i);
4332 final AppWindowToken wtoken = findAppWindowToken(token);
4333 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004334 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 + token + " (" + wtoken + ")");
4336 i--;
4337 N--;
4338 }
4339 }
4340 }
4341
Dianne Hackborna8f60182009-09-01 19:01:50 -07004342 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4343 boolean updateFocusAndLayout) {
4344 // First remove all of the windows from the list.
4345 tmpRemoveAppWindowsLocked(wtoken);
4346
4347 // Where to start adding?
4348 int pos = findWindowOffsetLocked(tokenPos);
4349
4350 // And now add them back at the correct place.
4351 pos = reAddAppWindowsLocked(pos, wtoken);
4352
4353 if (updateFocusAndLayout) {
4354 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4355 assignLayersLocked();
4356 }
4357 mLayoutNeeded = true;
4358 performLayoutAndPlaceSurfacesLocked();
4359 }
4360 }
4361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4363 // First remove all of the windows from the list.
4364 final int N = tokens.size();
4365 int i;
4366 for (i=0; i<N; i++) {
4367 WindowToken token = mTokenMap.get(tokens.get(i));
4368 if (token != null) {
4369 tmpRemoveAppWindowsLocked(token);
4370 }
4371 }
4372
4373 // Where to start adding?
4374 int pos = findWindowOffsetLocked(tokenPos);
4375
4376 // And now add them back at the correct place.
4377 for (i=0; i<N; i++) {
4378 WindowToken token = mTokenMap.get(tokens.get(i));
4379 if (token != null) {
4380 pos = reAddAppWindowsLocked(pos, token);
4381 }
4382 }
4383
Dianne Hackborna8f60182009-09-01 19:01:50 -07004384 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4385 assignLayersLocked();
4386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 mLayoutNeeded = true;
4388 performLayoutAndPlaceSurfacesLocked();
4389
4390 //dump();
4391 }
4392
4393 public void moveAppTokensToTop(List<IBinder> tokens) {
4394 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4395 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004396 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
4398
4399 final long origId = Binder.clearCallingIdentity();
4400 synchronized(mWindowMap) {
4401 removeAppTokensLocked(tokens);
4402 final int N = tokens.size();
4403 for (int i=0; i<N; i++) {
4404 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4405 if (wt != null) {
4406 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004407 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004408 mToTopApps.remove(wt);
4409 mToBottomApps.remove(wt);
4410 mToTopApps.add(wt);
4411 wt.sendingToBottom = false;
4412 wt.sendingToTop = true;
4413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 }
4415 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004416
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004417 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004418 moveAppWindowsLocked(tokens, mAppTokens.size());
4419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 }
4421 Binder.restoreCallingIdentity(origId);
4422 }
4423
4424 public void moveAppTokensToBottom(List<IBinder> tokens) {
4425 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4426 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004427 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 }
4429
4430 final long origId = Binder.clearCallingIdentity();
4431 synchronized(mWindowMap) {
4432 removeAppTokensLocked(tokens);
4433 final int N = tokens.size();
4434 int pos = 0;
4435 for (int i=0; i<N; i++) {
4436 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4437 if (wt != null) {
4438 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004439 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004440 mToTopApps.remove(wt);
4441 mToBottomApps.remove(wt);
4442 mToBottomApps.add(i, wt);
4443 wt.sendingToTop = false;
4444 wt.sendingToBottom = true;
4445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 pos++;
4447 }
4448 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004449
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004450 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004451 moveAppWindowsLocked(tokens, 0);
4452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
4454 Binder.restoreCallingIdentity(origId);
4455 }
4456
4457 // -------------------------------------------------------------
4458 // Misc IWindowSession methods
4459 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004460
Jim Miller284b62e2010-06-08 14:27:42 -07004461 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004462 {
Jim Miller284b62e2010-06-08 14:27:42 -07004463 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4464 // called before DevicePolicyManagerService has started.
4465 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4466 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4467 Context.DEVICE_POLICY_SERVICE);
4468 if (dpm != null) {
4469 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4470 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4471 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4472 }
Jim Millerd6b57052010-06-07 17:52:42 -07004473 }
Jim Miller284b62e2010-06-08 14:27:42 -07004474 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004475 }
4476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004478 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 != PackageManager.PERMISSION_GRANTED) {
4480 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4481 }
Jim Millerd6b57052010-06-07 17:52:42 -07004482
Jim Miller284b62e2010-06-08 14:27:42 -07004483 synchronized (mKeyguardTokenWatcher) {
4484 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 }
4487
4488 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004489 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 != PackageManager.PERMISSION_GRANTED) {
4491 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493
Jim Miller284b62e2010-06-08 14:27:42 -07004494 synchronized (mKeyguardTokenWatcher) {
4495 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004496
Jim Miller284b62e2010-06-08 14:27:42 -07004497 if (!mKeyguardTokenWatcher.isAcquired()) {
4498 // If we are the last one to reenable the keyguard wait until
4499 // we have actually finished reenabling until returning.
4500 // It is possible that reenableKeyguard() can be called before
4501 // the previous disableKeyguard() is handled, in which case
4502 // neither mKeyguardTokenWatcher.acquired() or released() would
4503 // be called. In that case mKeyguardDisabled will be false here
4504 // and we have nothing to wait for.
4505 while (mKeyguardDisabled) {
4506 try {
4507 mKeyguardTokenWatcher.wait();
4508 } catch (InterruptedException e) {
4509 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 }
4511 }
4512 }
4513 }
4514 }
4515
4516 /**
4517 * @see android.app.KeyguardManager#exitKeyguardSecurely
4518 */
4519 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004520 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 != PackageManager.PERMISSION_GRANTED) {
4522 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4523 }
4524 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4525 public void onKeyguardExitResult(boolean success) {
4526 try {
4527 callback.onKeyguardExitResult(success);
4528 } catch (RemoteException e) {
4529 // Client has died, we don't care.
4530 }
4531 }
4532 });
4533 }
4534
4535 public boolean inKeyguardRestrictedInputMode() {
4536 return mPolicy.inKeyguardRestrictedKeyInputMode();
4537 }
Romain Guy06882f82009-06-10 13:36:04 -07004538
Dianne Hackbornffa42482009-09-23 22:20:11 -07004539 public void closeSystemDialogs(String reason) {
4540 synchronized(mWindowMap) {
4541 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004542 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004543 if (w.mSurface != null) {
4544 try {
4545 w.mClient.closeSystemDialogs(reason);
4546 } catch (RemoteException e) {
4547 }
4548 }
4549 }
4550 }
4551 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004553 static float fixScale(float scale) {
4554 if (scale < 0) scale = 0;
4555 else if (scale > 20) scale = 20;
4556 return Math.abs(scale);
4557 }
Romain Guy06882f82009-06-10 13:36:04 -07004558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 public void setAnimationScale(int which, float scale) {
4560 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4561 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004562 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 }
4564
4565 if (scale < 0) scale = 0;
4566 else if (scale > 20) scale = 20;
4567 scale = Math.abs(scale);
4568 switch (which) {
4569 case 0: mWindowAnimationScale = fixScale(scale); break;
4570 case 1: mTransitionAnimationScale = fixScale(scale); break;
4571 }
Romain Guy06882f82009-06-10 13:36:04 -07004572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 // Persist setting
4574 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4575 }
Romain Guy06882f82009-06-10 13:36:04 -07004576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 public void setAnimationScales(float[] scales) {
4578 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4579 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004580 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 }
4582
4583 if (scales != null) {
4584 if (scales.length >= 1) {
4585 mWindowAnimationScale = fixScale(scales[0]);
4586 }
4587 if (scales.length >= 2) {
4588 mTransitionAnimationScale = fixScale(scales[1]);
4589 }
4590 }
Romain Guy06882f82009-06-10 13:36:04 -07004591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 // Persist setting
4593 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4594 }
Romain Guy06882f82009-06-10 13:36:04 -07004595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 public float getAnimationScale(int which) {
4597 switch (which) {
4598 case 0: return mWindowAnimationScale;
4599 case 1: return mTransitionAnimationScale;
4600 }
4601 return 0;
4602 }
Romain Guy06882f82009-06-10 13:36:04 -07004603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 public float[] getAnimationScales() {
4605 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4606 }
Romain Guy06882f82009-06-10 13:36:04 -07004607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004608 public int getSwitchState(int sw) {
4609 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4610 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004611 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004613 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 }
Romain Guy06882f82009-06-10 13:36:04 -07004615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 public int getSwitchStateForDevice(int devid, int sw) {
4617 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4618 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004619 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004621 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 }
Romain Guy06882f82009-06-10 13:36:04 -07004623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 public int getScancodeState(int sw) {
4625 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4626 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004627 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004629 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 }
Romain Guy06882f82009-06-10 13:36:04 -07004631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632 public int getScancodeStateForDevice(int devid, int sw) {
4633 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4634 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004635 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004637 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 }
Romain Guy06882f82009-06-10 13:36:04 -07004639
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004640 public int getTrackballScancodeState(int sw) {
4641 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4642 "getTrackballScancodeState()")) {
4643 throw new SecurityException("Requires READ_INPUT_STATE permission");
4644 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004645 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004646 }
4647
4648 public int getDPadScancodeState(int sw) {
4649 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4650 "getDPadScancodeState()")) {
4651 throw new SecurityException("Requires READ_INPUT_STATE permission");
4652 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004653 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004654 }
4655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 public int getKeycodeState(int sw) {
4657 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4658 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004659 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004661 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 }
Romain Guy06882f82009-06-10 13:36:04 -07004663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 public int getKeycodeStateForDevice(int devid, int sw) {
4665 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4666 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004667 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004668 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004669 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 }
Romain Guy06882f82009-06-10 13:36:04 -07004671
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004672 public int getTrackballKeycodeState(int sw) {
4673 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4674 "getTrackballKeycodeState()")) {
4675 throw new SecurityException("Requires READ_INPUT_STATE permission");
4676 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004677 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004678 }
4679
4680 public int getDPadKeycodeState(int sw) {
4681 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4682 "getDPadKeycodeState()")) {
4683 throw new SecurityException("Requires READ_INPUT_STATE permission");
4684 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004685 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004686 }
Jeff Browna41ca772010-08-11 14:46:32 -07004687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004689 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 }
Romain Guy06882f82009-06-10 13:36:04 -07004691
Jeff Browna41ca772010-08-11 14:46:32 -07004692 public InputChannel monitorInput(String inputChannelName) {
4693 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4694 "monitorInput()")) {
4695 throw new SecurityException("Requires READ_INPUT_STATE permission");
4696 }
4697 return mInputManager.monitorInput(inputChannelName);
4698 }
4699
Jeff Brown8d608662010-08-30 03:02:23 -07004700 public InputDevice getInputDevice(int deviceId) {
4701 return mInputManager.getInputDevice(deviceId);
4702 }
4703
4704 public int[] getInputDeviceIds() {
4705 return mInputManager.getInputDeviceIds();
4706 }
4707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 public void enableScreenAfterBoot() {
4709 synchronized(mWindowMap) {
4710 if (mSystemBooted) {
4711 return;
4712 }
4713 mSystemBooted = true;
4714 }
Romain Guy06882f82009-06-10 13:36:04 -07004715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 performEnableScreen();
4717 }
Romain Guy06882f82009-06-10 13:36:04 -07004718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 public void enableScreenIfNeededLocked() {
4720 if (mDisplayEnabled) {
4721 return;
4722 }
4723 if (!mSystemBooted) {
4724 return;
4725 }
4726 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4727 }
Romain Guy06882f82009-06-10 13:36:04 -07004728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 public void performEnableScreen() {
4730 synchronized(mWindowMap) {
4731 if (mDisplayEnabled) {
4732 return;
4733 }
4734 if (!mSystemBooted) {
4735 return;
4736 }
Romain Guy06882f82009-06-10 13:36:04 -07004737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 // Don't enable the screen until all existing windows
4739 // have been drawn.
4740 final int N = mWindows.size();
4741 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004742 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004743 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 return;
4745 }
4746 }
Romain Guy06882f82009-06-10 13:36:04 -07004747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 mDisplayEnabled = true;
4749 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004750 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 StringWriter sw = new StringWriter();
4752 PrintWriter pw = new PrintWriter(sw);
4753 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004754 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 }
4756 try {
4757 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4758 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004759 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 Parcel data = Parcel.obtain();
4761 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4762 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4763 data, null, 0);
4764 data.recycle();
4765 }
4766 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004767 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 }
4769 }
Romain Guy06882f82009-06-10 13:36:04 -07004770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004774 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4775 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 }
Romain Guy06882f82009-06-10 13:36:04 -07004777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 public void setInTouchMode(boolean mode) {
4779 synchronized(mWindowMap) {
4780 mInTouchMode = mode;
4781 }
4782 }
4783
Romain Guy06882f82009-06-10 13:36:04 -07004784 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004785 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004787 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004788 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 }
4790
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004791 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 }
Romain Guy06882f82009-06-10 13:36:04 -07004793
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004794 public void setRotationUnchecked(int rotation,
4795 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004796 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 long origId = Binder.clearCallingIdentity();
4800 boolean changed;
4801 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004802 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 }
Romain Guy06882f82009-06-10 13:36:04 -07004804
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004805 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 sendNewConfiguration();
4807 }
Romain Guy06882f82009-06-10 13:36:04 -07004808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004809 Binder.restoreCallingIdentity(origId);
4810 }
Romain Guy06882f82009-06-10 13:36:04 -07004811
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004812 /**
4813 * Apply a new rotation to the screen, respecting the requests of
4814 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4815 * re-evaluate the desired rotation.
4816 *
4817 * Returns null if the rotation has been changed. In this case YOU
4818 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4819 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004820 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 boolean changed;
4822 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4823 rotation = mRequestedRotation;
4824 } else {
4825 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004826 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004828 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004829 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004831 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004832 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004835 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 "Rotation changed to " + rotation
4837 + " from " + mRotation
4838 + " (forceApp=" + mForcedAppOrientation
4839 + ", req=" + mRequestedRotation + ")");
4840 mRotation = rotation;
4841 mWindowsFreezingScreen = true;
4842 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4843 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4844 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004845 mWaitingForConfig = true;
4846 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004848 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004849 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004850 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004851 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 }
4853 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004854 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 if (w.mSurface != null) {
4856 w.mOrientationChanging = true;
4857 }
4858 }
4859 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4860 try {
4861 mRotationWatchers.get(i).onRotationChanged(rotation);
4862 } catch (RemoteException e) {
4863 }
4864 }
4865 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 return changed;
4868 }
Romain Guy06882f82009-06-10 13:36:04 -07004869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 public int getRotation() {
4871 return mRotation;
4872 }
4873
4874 public int watchRotation(IRotationWatcher watcher) {
4875 final IBinder watcherBinder = watcher.asBinder();
4876 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4877 public void binderDied() {
4878 synchronized (mWindowMap) {
4879 for (int i=0; i<mRotationWatchers.size(); i++) {
4880 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004881 IRotationWatcher removed = mRotationWatchers.remove(i);
4882 if (removed != null) {
4883 removed.asBinder().unlinkToDeath(this, 0);
4884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004885 i--;
4886 }
4887 }
4888 }
4889 }
4890 };
Romain Guy06882f82009-06-10 13:36:04 -07004891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 synchronized (mWindowMap) {
4893 try {
4894 watcher.asBinder().linkToDeath(dr, 0);
4895 mRotationWatchers.add(watcher);
4896 } catch (RemoteException e) {
4897 // Client died, no cleanup needed.
4898 }
Romain Guy06882f82009-06-10 13:36:04 -07004899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 return mRotation;
4901 }
4902 }
4903
4904 /**
4905 * Starts the view server on the specified port.
4906 *
4907 * @param port The port to listener to.
4908 *
4909 * @return True if the server was successfully started, false otherwise.
4910 *
4911 * @see com.android.server.ViewServer
4912 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4913 */
4914 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004915 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 return false;
4917 }
4918
4919 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4920 return false;
4921 }
4922
4923 if (port < 1024) {
4924 return false;
4925 }
4926
4927 if (mViewServer != null) {
4928 if (!mViewServer.isRunning()) {
4929 try {
4930 return mViewServer.start();
4931 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004932 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 }
4934 }
4935 return false;
4936 }
4937
4938 try {
4939 mViewServer = new ViewServer(this, port);
4940 return mViewServer.start();
4941 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004942 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 }
4944 return false;
4945 }
4946
Romain Guy06882f82009-06-10 13:36:04 -07004947 private boolean isSystemSecure() {
4948 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4949 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4950 }
4951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 /**
4953 * Stops the view server if it exists.
4954 *
4955 * @return True if the server stopped, false if it wasn't started or
4956 * couldn't be stopped.
4957 *
4958 * @see com.android.server.ViewServer
4959 */
4960 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004961 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 return false;
4963 }
4964
4965 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4966 return false;
4967 }
4968
4969 if (mViewServer != null) {
4970 return mViewServer.stop();
4971 }
4972 return false;
4973 }
4974
4975 /**
4976 * Indicates whether the view server is running.
4977 *
4978 * @return True if the server is running, false otherwise.
4979 *
4980 * @see com.android.server.ViewServer
4981 */
4982 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07004983 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004984 return false;
4985 }
4986
4987 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4988 return false;
4989 }
4990
4991 return mViewServer != null && mViewServer.isRunning();
4992 }
4993
4994 /**
4995 * Lists all availble windows in the system. The listing is written in the
4996 * specified Socket's output stream with the following syntax:
4997 * windowHashCodeInHexadecimal windowName
4998 * Each line of the ouput represents a different window.
4999 *
5000 * @param client The remote client to send the listing to.
5001 * @return False if an error occured, true otherwise.
5002 */
5003 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005004 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 return false;
5006 }
5007
5008 boolean result = true;
5009
Jeff Browne33348b2010-07-15 23:54:05 -07005010 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005012 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005013 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005014 }
5015
5016 BufferedWriter out = null;
5017
5018 // Any uncaught exception will crash the system process
5019 try {
5020 OutputStream clientStream = client.getOutputStream();
5021 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5022
5023 final int count = windows.length;
5024 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005025 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 out.write(Integer.toHexString(System.identityHashCode(w)));
5027 out.write(' ');
5028 out.append(w.mAttrs.getTitle());
5029 out.write('\n');
5030 }
5031
5032 out.write("DONE.\n");
5033 out.flush();
5034 } catch (Exception e) {
5035 result = false;
5036 } finally {
5037 if (out != null) {
5038 try {
5039 out.close();
5040 } catch (IOException e) {
5041 result = false;
5042 }
5043 }
5044 }
5045
5046 return result;
5047 }
5048
5049 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005050 * Returns the focused window in the following format:
5051 * windowHashCodeInHexadecimal windowName
5052 *
5053 * @param client The remote client to send the listing to.
5054 * @return False if an error occurred, true otherwise.
5055 */
5056 boolean viewServerGetFocusedWindow(Socket client) {
5057 if (isSystemSecure()) {
5058 return false;
5059 }
5060
5061 boolean result = true;
5062
5063 WindowState focusedWindow = getFocusedWindow();
5064
5065 BufferedWriter out = null;
5066
5067 // Any uncaught exception will crash the system process
5068 try {
5069 OutputStream clientStream = client.getOutputStream();
5070 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5071
5072 if(focusedWindow != null) {
5073 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5074 out.write(' ');
5075 out.append(focusedWindow.mAttrs.getTitle());
5076 }
5077 out.write('\n');
5078 out.flush();
5079 } catch (Exception e) {
5080 result = false;
5081 } finally {
5082 if (out != null) {
5083 try {
5084 out.close();
5085 } catch (IOException e) {
5086 result = false;
5087 }
5088 }
5089 }
5090
5091 return result;
5092 }
5093
5094 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 * Sends a command to a target window. The result of the command, if any, will be
5096 * written in the output stream of the specified socket.
5097 *
5098 * The parameters must follow this syntax:
5099 * windowHashcode extra
5100 *
5101 * Where XX is the length in characeters of the windowTitle.
5102 *
5103 * The first parameter is the target window. The window with the specified hashcode
5104 * will be the target. If no target can be found, nothing happens. The extra parameters
5105 * will be delivered to the target window and as parameters to the command itself.
5106 *
5107 * @param client The remote client to sent the result, if any, to.
5108 * @param command The command to execute.
5109 * @param parameters The command parameters.
5110 *
5111 * @return True if the command was successfully delivered, false otherwise. This does
5112 * not indicate whether the command itself was successful.
5113 */
5114 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005115 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005116 return false;
5117 }
5118
5119 boolean success = true;
5120 Parcel data = null;
5121 Parcel reply = null;
5122
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005123 BufferedWriter out = null;
5124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005125 // Any uncaught exception will crash the system process
5126 try {
5127 // Find the hashcode of the window
5128 int index = parameters.indexOf(' ');
5129 if (index == -1) {
5130 index = parameters.length();
5131 }
5132 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005133 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134
5135 // Extract the command's parameter after the window description
5136 if (index < parameters.length()) {
5137 parameters = parameters.substring(index + 1);
5138 } else {
5139 parameters = "";
5140 }
5141
5142 final WindowManagerService.WindowState window = findWindow(hashCode);
5143 if (window == null) {
5144 return false;
5145 }
5146
5147 data = Parcel.obtain();
5148 data.writeInterfaceToken("android.view.IWindow");
5149 data.writeString(command);
5150 data.writeString(parameters);
5151 data.writeInt(1);
5152 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5153
5154 reply = Parcel.obtain();
5155
5156 final IBinder binder = window.mClient.asBinder();
5157 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5158 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5159
5160 reply.readException();
5161
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005162 if (!client.isOutputShutdown()) {
5163 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5164 out.write("DONE\n");
5165 out.flush();
5166 }
5167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005168 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005169 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170 success = false;
5171 } finally {
5172 if (data != null) {
5173 data.recycle();
5174 }
5175 if (reply != null) {
5176 reply.recycle();
5177 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005178 if (out != null) {
5179 try {
5180 out.close();
5181 } catch (IOException e) {
5182
5183 }
5184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 }
5186
5187 return success;
5188 }
5189
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005190 public void addWindowChangeListener(WindowChangeListener listener) {
5191 synchronized(mWindowMap) {
5192 mWindowChangeListeners.add(listener);
5193 }
5194 }
5195
5196 public void removeWindowChangeListener(WindowChangeListener listener) {
5197 synchronized(mWindowMap) {
5198 mWindowChangeListeners.remove(listener);
5199 }
5200 }
5201
5202 private void notifyWindowsChanged() {
5203 WindowChangeListener[] windowChangeListeners;
5204 synchronized(mWindowMap) {
5205 if(mWindowChangeListeners.isEmpty()) {
5206 return;
5207 }
5208 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5209 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5210 }
5211 int N = windowChangeListeners.length;
5212 for(int i = 0; i < N; i++) {
5213 windowChangeListeners[i].windowsChanged();
5214 }
5215 }
5216
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005217 private void notifyFocusChanged() {
5218 WindowChangeListener[] windowChangeListeners;
5219 synchronized(mWindowMap) {
5220 if(mWindowChangeListeners.isEmpty()) {
5221 return;
5222 }
5223 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5224 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5225 }
5226 int N = windowChangeListeners.length;
5227 for(int i = 0; i < N; i++) {
5228 windowChangeListeners[i].focusChanged();
5229 }
5230 }
5231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 private WindowState findWindow(int hashCode) {
5233 if (hashCode == -1) {
5234 return getFocusedWindow();
5235 }
5236
5237 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005238 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 final int count = windows.size();
5240
5241 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005242 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005243 if (System.identityHashCode(w) == hashCode) {
5244 return w;
5245 }
5246 }
5247 }
5248
5249 return null;
5250 }
5251
5252 /*
5253 * Instruct the Activity Manager to fetch the current configuration and broadcast
5254 * that to config-changed listeners if appropriate.
5255 */
5256 void sendNewConfiguration() {
5257 try {
5258 mActivityManager.updateConfiguration(null);
5259 } catch (RemoteException e) {
5260 }
5261 }
Romain Guy06882f82009-06-10 13:36:04 -07005262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 public Configuration computeNewConfiguration() {
5264 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005265 return computeNewConfigurationLocked();
5266 }
5267 }
Romain Guy06882f82009-06-10 13:36:04 -07005268
Dianne Hackbornc485a602009-03-24 22:39:49 -07005269 Configuration computeNewConfigurationLocked() {
5270 Configuration config = new Configuration();
5271 if (!computeNewConfigurationLocked(config)) {
5272 return null;
5273 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005274 return config;
5275 }
Romain Guy06882f82009-06-10 13:36:04 -07005276
Dianne Hackbornc485a602009-03-24 22:39:49 -07005277 boolean computeNewConfigurationLocked(Configuration config) {
5278 if (mDisplay == null) {
5279 return false;
5280 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005281
5282 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005283
5284 // Use the effective "visual" dimensions based on current rotation
5285 final boolean rotated = (mRotation == Surface.ROTATION_90
5286 || mRotation == Surface.ROTATION_270);
5287 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5288 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5289
Dianne Hackbornc485a602009-03-24 22:39:49 -07005290 int orientation = Configuration.ORIENTATION_SQUARE;
5291 if (dw < dh) {
5292 orientation = Configuration.ORIENTATION_PORTRAIT;
5293 } else if (dw > dh) {
5294 orientation = Configuration.ORIENTATION_LANDSCAPE;
5295 }
5296 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005297
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005298 DisplayMetrics dm = new DisplayMetrics();
5299 mDisplay.getMetrics(dm);
5300 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5301
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005302 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005303 // Note we only do this once because at this point we don't
5304 // expect the screen to change in this way at runtime, and want
5305 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005306 int longSize = dw;
5307 int shortSize = dh;
5308 if (longSize < shortSize) {
5309 int tmp = longSize;
5310 longSize = shortSize;
5311 shortSize = tmp;
5312 }
5313 longSize = (int)(longSize/dm.density);
5314 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005315
Dianne Hackborn723738c2009-06-25 19:48:04 -07005316 // These semi-magic numbers define our compatibility modes for
5317 // applications with different screens. Don't change unless you
5318 // make sure to test lots and lots of apps!
5319 if (longSize < 470) {
5320 // This is shorter than an HVGA normal density screen (which
5321 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005322 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5323 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005324 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005325 // What size is this screen screen?
5326 if (longSize >= 800 && shortSize >= 600) {
5327 // SVGA or larger screens at medium density are the point
5328 // at which we consider it to be an extra large screen.
5329 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5330 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005331 // VGA or larger screens at medium density are the point
5332 // at which we consider it to be a large screen.
5333 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5334 } else {
5335 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005336
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005337 // If this screen is wider than normal HVGA, or taller
5338 // than FWVGA, then for old apps we want to run in size
5339 // compatibility mode.
5340 if (shortSize > 321 || longSize > 570) {
5341 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5342 }
5343 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005344
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005345 // Is this a long screen?
5346 if (((longSize*3)/5) >= (shortSize-1)) {
5347 // Anything wider than WVGA (5:3) is considering to be long.
5348 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5349 } else {
5350 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5351 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005352 }
5353 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005354 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005355
Dianne Hackbornc485a602009-03-24 22:39:49 -07005356 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5357 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5358 mPolicy.adjustConfigurationLw(config);
5359 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005360 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005361
5362 // -------------------------------------------------------------
5363 // Drag and drop
5364 // -------------------------------------------------------------
5365
5366 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
5367 boolean localOnly, int width, int height, Surface outSurface) {
5368 if (DEBUG_DRAG) {
5369 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
5370 + " local=" + localOnly + " win=" + window
5371 + " asbinder=" + window.asBinder());
5372 }
5373
5374 final int callerPid = Binder.getCallingPid();
5375 final long origId = Binder.clearCallingIdentity();
5376 IBinder token = null;
5377
5378 try {
5379 synchronized (mWindowMap) {
5380 try {
5381 // !!! TODO: fail if the given window does not currently have touch focus?
5382
5383 if (mDragState == null) {
5384 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5385 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5386 outSurface.copyFrom(surface);
5387 token = new Binder();
5388 mDragState = new DragState(token, surface, localOnly);
5389 mDragState.mSurface = surface;
5390 mDragState.mLocalOnly = localOnly;
5391 token = mDragState.mToken = new Binder();
5392
5393 // 5 second timeout for this window to actually begin the drag
5394 mH.removeMessages(H.DRAG_START_TIMEOUT, window);
5395 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, window.asBinder());
5396 mH.sendMessageDelayed(msg, 5000);
5397 } else {
5398 Slog.w(TAG, "Drag already in progress");
5399 }
5400 } catch (Surface.OutOfResourcesException e) {
5401 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5402 if (mDragState != null) {
5403 mDragState.reset();
5404 mDragState = null;
5405 }
5406
5407 }
5408 }
5409 } finally {
5410 Binder.restoreCallingIdentity(origId);
5411 }
5412
5413 return token;
5414 }
5415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005416 // -------------------------------------------------------------
5417 // Input Events and Focus Management
5418 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005419
Jeff Brown349703e2010-06-22 01:27:15 -07005420 InputMonitor mInputMonitor = new InputMonitor();
5421
5422 /* Tracks the progress of input dispatch and ensures that input dispatch state
5423 * is kept in sync with changes in window focus, visibility, registration, and
5424 * other relevant Window Manager state transitions. */
5425 final class InputMonitor {
5426 // Current window with input focus for keys and other non-touch events. May be null.
5427 private WindowState mInputFocus;
5428
5429 // When true, prevents input dispatch from proceeding until set to false again.
5430 private boolean mInputDispatchFrozen;
5431
5432 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5433 private boolean mInputDispatchEnabled = true;
5434
5435 // Temporary list of windows information to provide to the input dispatcher.
5436 private InputWindowList mTempInputWindows = new InputWindowList();
5437
5438 // Temporary input application object to provide to the input dispatcher.
5439 private InputApplication mTempInputApplication = new InputApplication();
5440
5441 /* Notifies the window manager about a broken input channel.
5442 *
5443 * Called by the InputManager.
5444 */
5445 public void notifyInputChannelBroken(InputChannel inputChannel) {
5446 synchronized (mWindowMap) {
5447 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5448 if (windowState == null) {
5449 return; // irrelevant
5450 }
5451
5452 Slog.i(TAG, "WINDOW DIED " + windowState);
5453 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005454 }
5455 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005456
Jeff Brown519e0242010-09-15 15:18:56 -07005457 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005458 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005459 *
5460 * Called by the InputManager.
5461 */
Jeff Brown519e0242010-09-15 15:18:56 -07005462 public long notifyANR(Object token, InputChannel inputChannel) {
5463 AppWindowToken appWindowToken = null;
5464 if (inputChannel != null) {
5465 synchronized (mWindowMap) {
5466 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5467 if (windowState != null) {
5468 Slog.i(TAG, "Input event dispatching timed out sending to "
5469 + windowState.mAttrs.getTitle());
5470 appWindowToken = windowState.mAppToken;
5471 }
Jeff Brown349703e2010-06-22 01:27:15 -07005472 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005473 }
5474
Jeff Brown519e0242010-09-15 15:18:56 -07005475 if (appWindowToken == null && token != null) {
5476 appWindowToken = (AppWindowToken) token;
5477 Slog.i(TAG, "Input event dispatching timed out sending to application "
5478 + appWindowToken.stringName);
5479 }
Jeff Brown349703e2010-06-22 01:27:15 -07005480
Jeff Brown519e0242010-09-15 15:18:56 -07005481 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005482 try {
5483 // Notify the activity manager about the timeout and let it decide whether
5484 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005485 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005486 if (! abort) {
5487 // The activity manager declined to abort dispatching.
5488 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005489 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005490 }
Jeff Brown349703e2010-06-22 01:27:15 -07005491 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005492 }
5493 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005494 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005495 }
5496
Jeff Brown349703e2010-06-22 01:27:15 -07005497 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5498 synchronized (mWindowMap) {
5499 return getWindowStateForInputChannelLocked(inputChannel);
5500 }
5501 }
5502
5503 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5504 int windowCount = mWindows.size();
5505 for (int i = 0; i < windowCount; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005506 WindowState windowState = mWindows.get(i);
Jeff Brown349703e2010-06-22 01:27:15 -07005507 if (windowState.mInputChannel == inputChannel) {
5508 return windowState;
5509 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005510 }
5511
Jeff Brown349703e2010-06-22 01:27:15 -07005512 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005513 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005514
5515 private void addDragInputWindow(InputWindowList windowList) {
5516 final InputWindow inputWindow = windowList.add();
5517 inputWindow.inputChannel = mDragState.mServerChannel;
5518 inputWindow.name = "drag";
5519 inputWindow.layoutParamsFlags = 0;
5520 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5521 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5522 inputWindow.visible = true;
5523 inputWindow.canReceiveKeys = false;
5524 inputWindow.hasFocus = true;
5525 inputWindow.hasWallpaper = false;
5526 inputWindow.paused = false;
5527 inputWindow.layer = mPolicy.windowTypeToLayerLw(inputWindow.layoutParamsType)
5528 * TYPE_LAYER_MULTIPLIER
5529 + TYPE_LAYER_OFFSET;
5530 inputWindow.ownerPid = Process.myPid();
5531 inputWindow.ownerUid = Process.myUid();
5532
5533 // The drag window covers the entire display
5534 inputWindow.frameLeft = 0;
5535 inputWindow.frameTop = 0;
5536 inputWindow.frameRight = mDisplay.getWidth();
5537 inputWindow.frameBottom = mDisplay.getHeight();
5538
5539 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5540 inputWindow.visibleFrameTop = inputWindow.frameTop;
5541 inputWindow.visibleFrameRight = inputWindow.frameRight;
5542 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5543
5544 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5545 inputWindow.touchableAreaTop = inputWindow.frameTop;
5546 inputWindow.touchableAreaRight = inputWindow.frameRight;
5547 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5548 }
5549
Jeff Brown349703e2010-06-22 01:27:15 -07005550 /* Updates the cached window information provided to the input dispatcher. */
5551 public void updateInputWindowsLw() {
5552 // Populate the input window list with information about all of the windows that
5553 // could potentially receive input.
5554 // As an optimization, we could try to prune the list of windows but this turns
5555 // out to be difficult because only the native code knows for sure which window
5556 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005557 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005558
5559 // If there's a drag in flight, provide a pseudowindow to catch drag input
5560 final boolean inDrag = (mDragState != null);
5561 if (inDrag) {
5562 if (DEBUG_DRAG) {
5563 Log.d(TAG, "Inserting drag window");
5564 }
5565 addDragInputWindow(mTempInputWindows);
5566 }
5567
Jeff Brown7fbdc842010-06-17 20:52:56 -07005568 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005569 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005570 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005571 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005572 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005573 continue;
5574 }
5575
Jeff Brown349703e2010-06-22 01:27:15 -07005576 final int flags = child.mAttrs.flags;
5577 final int type = child.mAttrs.type;
5578
5579 final boolean hasFocus = (child == mInputFocus);
5580 final boolean isVisible = child.isVisibleLw();
5581 final boolean hasWallpaper = (child == mWallpaperTarget)
5582 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005583
5584 // If there's a drag in progress and 'child' is a potential drop target,
5585 // make sure it's been told about the drag
5586 if (inDrag && isVisible) {
5587 mDragState.sendDragStartedIfNeededLw(child);
5588 }
5589
Jeff Brown349703e2010-06-22 01:27:15 -07005590 // Add a window to our list of input windows.
5591 final InputWindow inputWindow = mTempInputWindows.add();
5592 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005593 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005594 inputWindow.layoutParamsFlags = flags;
5595 inputWindow.layoutParamsType = type;
5596 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5597 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005598 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005599 inputWindow.hasFocus = hasFocus;
5600 inputWindow.hasWallpaper = hasWallpaper;
5601 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005602 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005603 inputWindow.ownerPid = child.mSession.mPid;
5604 inputWindow.ownerUid = child.mSession.mUid;
5605
5606 final Rect frame = child.mFrame;
5607 inputWindow.frameLeft = frame.left;
5608 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005609 inputWindow.frameRight = frame.right;
5610 inputWindow.frameBottom = frame.bottom;
5611
5612 final Rect visibleFrame = child.mVisibleFrame;
5613 inputWindow.visibleFrameLeft = visibleFrame.left;
5614 inputWindow.visibleFrameTop = visibleFrame.top;
5615 inputWindow.visibleFrameRight = visibleFrame.right;
5616 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005617
5618 switch (child.mTouchableInsets) {
5619 default:
5620 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5621 inputWindow.touchableAreaLeft = frame.left;
5622 inputWindow.touchableAreaTop = frame.top;
5623 inputWindow.touchableAreaRight = frame.right;
5624 inputWindow.touchableAreaBottom = frame.bottom;
5625 break;
5626
5627 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5628 Rect inset = child.mGivenContentInsets;
5629 inputWindow.touchableAreaLeft = frame.left + inset.left;
5630 inputWindow.touchableAreaTop = frame.top + inset.top;
5631 inputWindow.touchableAreaRight = frame.right - inset.right;
5632 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5633 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005634 }
Jeff Brown349703e2010-06-22 01:27:15 -07005635
5636 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5637 Rect inset = child.mGivenVisibleInsets;
5638 inputWindow.touchableAreaLeft = frame.left + inset.left;
5639 inputWindow.touchableAreaTop = frame.top + inset.top;
5640 inputWindow.touchableAreaRight = frame.right - inset.right;
5641 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005642 break;
5643 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005644 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005645 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005646
Jeff Brown349703e2010-06-22 01:27:15 -07005647 // Send windows to native code.
5648 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005649
Jeff Brown349703e2010-06-22 01:27:15 -07005650 // Clear the list in preparation for the next round.
5651 // Also avoids keeping InputChannel objects referenced unnecessarily.
5652 mTempInputWindows.clear();
5653 }
5654
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005655 /* Provides feedback for a virtual key down. */
5656 public void virtualKeyDownFeedback() {
5657 synchronized (mWindowMap) {
5658 mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
5659 }
5660 }
5661
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005662 /* Notifies that the lid switch changed state. */
5663 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5664 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5665 }
5666
Jeff Brown349703e2010-06-22 01:27:15 -07005667 /* Provides an opportunity for the window manager policy to intercept early key
5668 * processing as soon as the key has been read from the device. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005669 public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
5670 int policyFlags, boolean isScreenOn) {
5671 return mPolicy.interceptKeyBeforeQueueing(whenNanos,
5672 keyCode, down, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005673 }
5674
5675 /* Provides an opportunity for the window manager policy to process a key before
5676 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005677 public boolean interceptKeyBeforeDispatching(InputChannel focus,
5678 int action, int flags, int keyCode, int metaState, int repeatCount,
5679 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005680 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005681 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
5682 keyCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005683 }
5684
5685 /* Called when the current input focus changes.
5686 * Layer assignment is assumed to be complete by the time this is called.
5687 */
5688 public void setInputFocusLw(WindowState newWindow) {
5689 if (DEBUG_INPUT) {
5690 Slog.d(TAG, "Input focus has changed to " + newWindow);
5691 }
5692
5693 if (newWindow != mInputFocus) {
5694 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005695 // Displaying a window implicitly causes dispatching to be unpaused.
5696 // This is to protect against bugs if someone pauses dispatching but
5697 // forgets to resume.
5698 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005699 }
Jeff Brown349703e2010-06-22 01:27:15 -07005700
5701 mInputFocus = newWindow;
5702 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005703 }
5704 }
5705
Jeff Brown349703e2010-06-22 01:27:15 -07005706 public void setFocusedAppLw(AppWindowToken newApp) {
5707 // Focused app has changed.
5708 if (newApp == null) {
5709 mInputManager.setFocusedApplication(null);
5710 } else {
5711 mTempInputApplication.name = newApp.toString();
5712 mTempInputApplication.dispatchingTimeoutNanos =
5713 newApp.inputDispatchingTimeoutNanos;
5714 mTempInputApplication.token = newApp;
5715
5716 mInputManager.setFocusedApplication(mTempInputApplication);
5717 }
5718 }
5719
Jeff Brown349703e2010-06-22 01:27:15 -07005720 public void pauseDispatchingLw(WindowToken window) {
5721 if (! window.paused) {
5722 if (DEBUG_INPUT) {
5723 Slog.v(TAG, "Pausing WindowToken " + window);
5724 }
5725
5726 window.paused = true;
5727 updateInputWindowsLw();
5728 }
5729 }
5730
5731 public void resumeDispatchingLw(WindowToken window) {
5732 if (window.paused) {
5733 if (DEBUG_INPUT) {
5734 Slog.v(TAG, "Resuming WindowToken " + window);
5735 }
5736
5737 window.paused = false;
5738 updateInputWindowsLw();
5739 }
5740 }
5741
5742 public void freezeInputDispatchingLw() {
5743 if (! mInputDispatchFrozen) {
5744 if (DEBUG_INPUT) {
5745 Slog.v(TAG, "Freezing input dispatching");
5746 }
5747
5748 mInputDispatchFrozen = true;
5749 updateInputDispatchModeLw();
5750 }
5751 }
5752
5753 public void thawInputDispatchingLw() {
5754 if (mInputDispatchFrozen) {
5755 if (DEBUG_INPUT) {
5756 Slog.v(TAG, "Thawing input dispatching");
5757 }
5758
5759 mInputDispatchFrozen = false;
5760 updateInputDispatchModeLw();
5761 }
5762 }
5763
5764 public void setEventDispatchingLw(boolean enabled) {
5765 if (mInputDispatchEnabled != enabled) {
5766 if (DEBUG_INPUT) {
5767 Slog.v(TAG, "Setting event dispatching to " + enabled);
5768 }
5769
5770 mInputDispatchEnabled = enabled;
5771 updateInputDispatchModeLw();
5772 }
5773 }
5774
5775 private void updateInputDispatchModeLw() {
5776 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5777 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005780 public void pauseKeyDispatching(IBinder _token) {
5781 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5782 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005783 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005784 }
5785
5786 synchronized (mWindowMap) {
5787 WindowToken token = mTokenMap.get(_token);
5788 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005789 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
5791 }
5792 }
5793
5794 public void resumeKeyDispatching(IBinder _token) {
5795 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5796 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005797 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005798 }
5799
5800 synchronized (mWindowMap) {
5801 WindowToken token = mTokenMap.get(_token);
5802 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005803 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 }
5805 }
5806 }
5807
5808 public void setEventDispatching(boolean enabled) {
5809 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5810 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005811 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 }
5813
5814 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005815 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 }
5817 }
Romain Guy06882f82009-06-10 13:36:04 -07005818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005819 /**
5820 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005821 * Even when sync is false, this method may block while waiting for current
5822 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005823 *
5824 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 * {@link SystemClock#uptimeMillis()} as the timebase.)
5826 * @param sync If true, wait for the event to be completed before returning to the caller.
5827 * @return Returns true if event was dispatched, false if it was dropped for any reason
5828 */
5829 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5830 long downTime = ev.getDownTime();
5831 long eventTime = ev.getEventTime();
5832
5833 int action = ev.getAction();
5834 int code = ev.getKeyCode();
5835 int repeatCount = ev.getRepeatCount();
5836 int metaState = ev.getMetaState();
5837 int deviceId = ev.getDeviceId();
5838 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005839 int source = ev.getSource();
5840
5841 if (source == InputDevice.SOURCE_UNKNOWN) {
5842 source = InputDevice.SOURCE_KEYBOARD;
5843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844
5845 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5846 if (downTime == 0) downTime = eventTime;
5847
5848 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jeff Brownc5ed5912010-07-14 18:48:53 -07005849 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005850
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005851 final int pid = Binder.getCallingPid();
5852 final int uid = Binder.getCallingUid();
5853 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005854
Jeff Brownbbda99d2010-07-28 15:48:59 -07005855 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5856 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5857 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5858 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005859
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005860 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005861 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 }
5863
5864 /**
5865 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005866 * Even when sync is false, this method may block while waiting for current
5867 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005868 *
5869 * @param ev A motion event describing the pointer (touch) action. (As noted in
5870 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005871 * {@link SystemClock#uptimeMillis()} as the timebase.)
5872 * @param sync If true, wait for the event to be completed before returning to the caller.
5873 * @return Returns true if event was dispatched, false if it was dropped for any reason
5874 */
5875 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005876 final int pid = Binder.getCallingPid();
5877 final int uid = Binder.getCallingUid();
5878 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005879
Jeff Brownc5ed5912010-07-14 18:48:53 -07005880 MotionEvent newEvent = MotionEvent.obtain(ev);
5881 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5882 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5883 }
5884
Jeff Brownbbda99d2010-07-28 15:48:59 -07005885 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5886 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5887 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5888 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005889
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005890 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005891 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005892 }
Romain Guy06882f82009-06-10 13:36:04 -07005893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 /**
5895 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005896 * Even when sync is false, this method may block while waiting for current
5897 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005898 *
5899 * @param ev A motion event describing the trackball action. (As noted in
5900 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901 * {@link SystemClock#uptimeMillis()} as the timebase.)
5902 * @param sync If true, wait for the event to be completed before returning to the caller.
5903 * @return Returns true if event was dispatched, false if it was dropped for any reason
5904 */
5905 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005906 final int pid = Binder.getCallingPid();
5907 final int uid = Binder.getCallingUid();
5908 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005909
Jeff Brownc5ed5912010-07-14 18:48:53 -07005910 MotionEvent newEvent = MotionEvent.obtain(ev);
5911 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5912 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5913 }
5914
Jeff Brownbbda99d2010-07-28 15:48:59 -07005915 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5916 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5917 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5918 INJECTION_TIMEOUT_MILLIS);
5919
5920 Binder.restoreCallingIdentity(ident);
5921 return reportInjectionResult(result);
5922 }
5923
5924 /**
5925 * Inject an input event into the UI without waiting for dispatch to commence.
5926 * This variant is useful for fire-and-forget input event injection. It does not
5927 * block any longer than it takes to enqueue the input event.
5928 *
5929 * @param ev An input event. (Be sure to set the input source correctly.)
5930 * @return Returns true if event was dispatched, false if it was dropped for any reason
5931 */
5932 public boolean injectInputEventNoWait(InputEvent ev) {
5933 final int pid = Binder.getCallingPid();
5934 final int uid = Binder.getCallingUid();
5935 final long ident = Binder.clearCallingIdentity();
5936
5937 final int result = mInputManager.injectInputEvent(ev, pid, uid,
5938 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
5939 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005940
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005941 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005942 return reportInjectionResult(result);
5943 }
5944
5945 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005946 switch (result) {
5947 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5948 Slog.w(TAG, "Input event injection permission denied.");
5949 throw new SecurityException(
5950 "Injecting to another application requires INJECT_EVENTS permission");
5951 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07005952 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005953 return true;
5954 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5955 Slog.w(TAG, "Input event injection timed out.");
5956 return false;
5957 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5958 default:
5959 Slog.w(TAG, "Input event injection failed.");
5960 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005962 }
Romain Guy06882f82009-06-10 13:36:04 -07005963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 private WindowState getFocusedWindow() {
5965 synchronized (mWindowMap) {
5966 return getFocusedWindowLocked();
5967 }
5968 }
5969
5970 private WindowState getFocusedWindowLocked() {
5971 return mCurrentFocus;
5972 }
Romain Guy06882f82009-06-10 13:36:04 -07005973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 public boolean detectSafeMode() {
5975 mSafeMode = mPolicy.detectSafeMode();
5976 return mSafeMode;
5977 }
Romain Guy06882f82009-06-10 13:36:04 -07005978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07005980 synchronized(mWindowMap) {
5981 if (mDisplay != null) {
5982 throw new IllegalStateException("Display already initialized");
5983 }
5984 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
5985 mDisplay = wm.getDefaultDisplay();
5986 mInitialDisplayWidth = mDisplay.getWidth();
5987 mInitialDisplayHeight = mDisplay.getHeight();
5988 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
5989 }
5990
5991 try {
5992 mActivityManager.updateConfiguration(null);
5993 } catch (RemoteException e) {
5994 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07005995
5996 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07005997 }
5998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 // -------------------------------------------------------------
6000 // Client Session State
6001 // -------------------------------------------------------------
6002
6003 private final class Session extends IWindowSession.Stub
6004 implements IBinder.DeathRecipient {
6005 final IInputMethodClient mClient;
6006 final IInputContext mInputContext;
6007 final int mUid;
6008 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006009 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006010 SurfaceSession mSurfaceSession;
6011 int mNumWindow = 0;
6012 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006014 public Session(IInputMethodClient client, IInputContext inputContext) {
6015 mClient = client;
6016 mInputContext = inputContext;
6017 mUid = Binder.getCallingUid();
6018 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006019 StringBuilder sb = new StringBuilder();
6020 sb.append("Session{");
6021 sb.append(Integer.toHexString(System.identityHashCode(this)));
6022 sb.append(" uid ");
6023 sb.append(mUid);
6024 sb.append("}");
6025 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 synchronized (mWindowMap) {
6028 if (mInputMethodManager == null && mHaveInputMethods) {
6029 IBinder b = ServiceManager.getService(
6030 Context.INPUT_METHOD_SERVICE);
6031 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6032 }
6033 }
6034 long ident = Binder.clearCallingIdentity();
6035 try {
6036 // Note: it is safe to call in to the input method manager
6037 // here because we are not holding our lock.
6038 if (mInputMethodManager != null) {
6039 mInputMethodManager.addClient(client, inputContext,
6040 mUid, mPid);
6041 } else {
6042 client.setUsingInputMethod(false);
6043 }
6044 client.asBinder().linkToDeath(this, 0);
6045 } catch (RemoteException e) {
6046 // The caller has died, so we can just forget about this.
6047 try {
6048 if (mInputMethodManager != null) {
6049 mInputMethodManager.removeClient(client);
6050 }
6051 } catch (RemoteException ee) {
6052 }
6053 } finally {
6054 Binder.restoreCallingIdentity(ident);
6055 }
6056 }
Romain Guy06882f82009-06-10 13:36:04 -07006057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 @Override
6059 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6060 throws RemoteException {
6061 try {
6062 return super.onTransact(code, data, reply, flags);
6063 } catch (RuntimeException e) {
6064 // Log all 'real' exceptions thrown to the caller
6065 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006066 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006067 }
6068 throw e;
6069 }
6070 }
6071
6072 public void binderDied() {
6073 // Note: it is safe to call in to the input method manager
6074 // here because we are not holding our lock.
6075 try {
6076 if (mInputMethodManager != null) {
6077 mInputMethodManager.removeClient(mClient);
6078 }
6079 } catch (RemoteException e) {
6080 }
6081 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006082 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 mClientDead = true;
6084 killSessionLocked();
6085 }
6086 }
6087
6088 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006089 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6090 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6091 outInputChannel);
6092 }
6093
6094 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006096 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 }
Romain Guy06882f82009-06-10 13:36:04 -07006098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099 public void remove(IWindow window) {
6100 removeWindow(this, window);
6101 }
Romain Guy06882f82009-06-10 13:36:04 -07006102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6104 int requestedWidth, int requestedHeight, int viewFlags,
6105 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006106 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006107 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6108 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006110 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006111 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6112 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 }
Romain Guy06882f82009-06-10 13:36:04 -07006114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 public void setTransparentRegion(IWindow window, Region region) {
6116 setTransparentRegionWindow(this, window, region);
6117 }
Romain Guy06882f82009-06-10 13:36:04 -07006118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006119 public void setInsets(IWindow window, int touchableInsets,
6120 Rect contentInsets, Rect visibleInsets) {
6121 setInsetsWindow(this, window, touchableInsets, contentInsets,
6122 visibleInsets);
6123 }
Romain Guy06882f82009-06-10 13:36:04 -07006124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006125 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6126 getWindowDisplayFrame(this, window, outDisplayFrame);
6127 }
Romain Guy06882f82009-06-10 13:36:04 -07006128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006130 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006131 TAG, "IWindow finishDrawing called for " + window);
6132 finishDrawingWindow(this, window);
6133 }
6134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006135 public void setInTouchMode(boolean mode) {
6136 synchronized(mWindowMap) {
6137 mInTouchMode = mode;
6138 }
6139 }
6140
6141 public boolean getInTouchMode() {
6142 synchronized(mWindowMap) {
6143 return mInTouchMode;
6144 }
6145 }
6146
6147 public boolean performHapticFeedback(IWindow window, int effectId,
6148 boolean always) {
6149 synchronized(mWindowMap) {
6150 long ident = Binder.clearCallingIdentity();
6151 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006152 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006153 windowForClientLocked(this, window, true),
6154 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 } finally {
6156 Binder.restoreCallingIdentity(ident);
6157 }
6158 }
6159 }
Romain Guy06882f82009-06-10 13:36:04 -07006160
Christopher Tatea53146c2010-09-07 11:57:52 -07006161 /* Drag/drop */
6162 public IBinder prepareDrag(IWindow window, boolean localOnly,
6163 int width, int height, Surface outSurface) {
6164 return prepareDragSurface(window, mSurfaceSession, localOnly,
6165 width, height, outSurface);
6166 }
6167
6168 public boolean performDrag(IWindow window, IBinder dragToken,
6169 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6170 ClipData data) {
6171 if (DEBUG_DRAG) {
6172 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6173 }
6174
6175 synchronized (mWindowMap) {
6176 if (mDragState == null) {
6177 Slog.w(TAG, "No drag prepared");
6178 throw new IllegalStateException("performDrag() without prepareDrag()");
6179 }
6180
6181 if (dragToken != mDragState.mToken) {
6182 Slog.w(TAG, "Performing mismatched drag");
6183 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6184 }
6185
6186 WindowState callingWin = windowForClientLocked(null, window, false);
6187 if (callingWin == null) {
6188 Slog.w(TAG, "Bad requesting window " + window);
6189 return false; // !!! TODO: throw here?
6190 }
6191
6192 // !!! TODO: if input is not still focused on the initiating window, fail
6193 // the drag initiation (e.g. an alarm window popped up just as the application
6194 // called performDrag()
6195
6196 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6197
6198 // !!! TODO: call into the input monitor to sever the current touch event flow
6199 // and redirect to the drag "window"; also extract the current touch (x, y)
6200 // in screen coordinates
6201
6202 mDragState.register();
6203 mInputMonitor.updateInputWindowsLw();
6204 mInputManager.transferTouchFocus(callingWin.mInputChannel,
6205 mDragState.mServerChannel);
6206
6207 mDragState.mData = data;
6208 mDragState.broadcastDragStartedLw();
6209
6210 // remember the thumb offsets for later
6211 mDragState.mThumbOffsetX = thumbCenterX;
6212 mDragState.mThumbOffsetY = thumbCenterY;
6213
6214 // Make the surface visible at the proper location
6215 final Surface surface = mDragState.mSurface;
6216 surface.openTransaction();
6217 try {
6218 surface.setPosition((int)(touchX - thumbCenterX),
6219 (int)(touchY - thumbCenterY));
6220 surface.setAlpha(.5f);
6221 surface.show();
6222 } finally {
6223 surface.closeTransaction();
6224 }
6225 }
6226
6227 return true; // success!
6228 }
6229
6230 public void dragRecipientEntered(IWindow window) {
6231 if (DEBUG_DRAG) {
6232 Slog.d(TAG, "Drag into new candidate view @ " + window);
6233 }
6234 }
6235
6236 public void dragRecipientExited(IWindow window) {
6237 if (DEBUG_DRAG) {
6238 Slog.d(TAG, "Drag from old candidate view @ " + window);
6239 }
6240 }
6241
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006242 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006243 synchronized(mWindowMap) {
6244 long ident = Binder.clearCallingIdentity();
6245 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006246 setWindowWallpaperPositionLocked(
6247 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006248 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006249 } finally {
6250 Binder.restoreCallingIdentity(ident);
6251 }
6252 }
6253 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006254
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006255 public void wallpaperOffsetsComplete(IBinder window) {
6256 WindowManagerService.this.wallpaperOffsetsComplete(window);
6257 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006258
Dianne Hackborn75804932009-10-20 20:15:20 -07006259 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6260 int z, Bundle extras, boolean sync) {
6261 synchronized(mWindowMap) {
6262 long ident = Binder.clearCallingIdentity();
6263 try {
6264 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006265 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006266 action, x, y, z, extras, sync);
6267 } finally {
6268 Binder.restoreCallingIdentity(ident);
6269 }
6270 }
6271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006272
Dianne Hackborn75804932009-10-20 20:15:20 -07006273 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6274 WindowManagerService.this.wallpaperCommandComplete(window, result);
6275 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 void windowAddedLocked() {
6278 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006279 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006280 TAG, "First window added to " + this + ", creating SurfaceSession");
6281 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006282 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006283 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006284 mSessions.add(this);
6285 }
6286 mNumWindow++;
6287 }
6288
6289 void windowRemovedLocked() {
6290 mNumWindow--;
6291 killSessionLocked();
6292 }
Romain Guy06882f82009-06-10 13:36:04 -07006293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 void killSessionLocked() {
6295 if (mNumWindow <= 0 && mClientDead) {
6296 mSessions.remove(this);
6297 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006298 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 TAG, "Last window removed from " + this
6300 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006301 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006302 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006303 try {
6304 mSurfaceSession.kill();
6305 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006306 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 + mSurfaceSession + " in session " + this
6308 + ": " + e.toString());
6309 }
6310 mSurfaceSession = null;
6311 }
6312 }
6313 }
Romain Guy06882f82009-06-10 13:36:04 -07006314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006315 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006316 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6317 pw.print(" mClientDead="); pw.print(mClientDead);
6318 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 }
6320
6321 @Override
6322 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006323 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006324 }
6325 }
6326
6327 // -------------------------------------------------------------
6328 // Client Window State
6329 // -------------------------------------------------------------
6330
6331 private final class WindowState implements WindowManagerPolicy.WindowState {
6332 final Session mSession;
6333 final IWindow mClient;
6334 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006335 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 AppWindowToken mAppToken;
6337 AppWindowToken mTargetAppToken;
6338 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6339 final DeathRecipient mDeathRecipient;
6340 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006341 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 final int mBaseLayer;
6343 final int mSubLayer;
6344 final boolean mLayoutAttached;
6345 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006346 final boolean mIsWallpaper;
6347 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006348 int mViewVisibility;
6349 boolean mPolicyVisibility = true;
6350 boolean mPolicyVisibilityAfterAnim = true;
6351 boolean mAppFreezing;
6352 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006353 boolean mReportDestroySurface;
6354 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 boolean mAttachedHidden; // is our parent window hidden?
6356 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006357 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 int mRequestedWidth;
6359 int mRequestedHeight;
6360 int mLastRequestedWidth;
6361 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 int mLayer;
6363 int mAnimLayer;
6364 int mLastLayer;
6365 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006366 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006367 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006369 int mLayoutSeq = -1;
6370
6371 Configuration mConfiguration = null;
6372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006373 // Actual frame shown on-screen (may be modified by animation)
6374 final Rect mShownFrame = new Rect();
6375 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006377 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006378 * Set when we have changed the size of the surface, to know that
6379 * we must tell them application to resize (and thus redraw itself).
6380 */
6381 boolean mSurfaceResized;
6382
6383 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 * Insets that determine the actually visible area
6385 */
6386 final Rect mVisibleInsets = new Rect();
6387 final Rect mLastVisibleInsets = new Rect();
6388 boolean mVisibleInsetsChanged;
6389
6390 /**
6391 * Insets that are covered by system windows
6392 */
6393 final Rect mContentInsets = new Rect();
6394 final Rect mLastContentInsets = new Rect();
6395 boolean mContentInsetsChanged;
6396
6397 /**
6398 * Set to true if we are waiting for this window to receive its
6399 * given internal insets before laying out other windows based on it.
6400 */
6401 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 /**
6404 * These are the content insets that were given during layout for
6405 * this window, to be applied to windows behind it.
6406 */
6407 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006409 /**
6410 * These are the visible insets that were given during layout for
6411 * this window, to be applied to windows behind it.
6412 */
6413 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006415 /**
6416 * Flag indicating whether the touchable region should be adjusted by
6417 * the visible insets; if false the area outside the visible insets is
6418 * NOT touchable, so we must use those to adjust the frame during hit
6419 * tests.
6420 */
6421 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006423 // Current transformation being applied.
6424 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6425 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6426 float mHScale=1, mVScale=1;
6427 float mLastHScale=1, mLastVScale=1;
6428 final Matrix mTmpMatrix = new Matrix();
6429
6430 // "Real" frame that the application sees.
6431 final Rect mFrame = new Rect();
6432 final Rect mLastFrame = new Rect();
6433
6434 final Rect mContainingFrame = new Rect();
6435 final Rect mDisplayFrame = new Rect();
6436 final Rect mContentFrame = new Rect();
6437 final Rect mVisibleFrame = new Rect();
6438
6439 float mShownAlpha = 1;
6440 float mAlpha = 1;
6441 float mLastAlpha = 1;
6442
6443 // Set to true if, when the window gets displayed, it should perform
6444 // an enter animation.
6445 boolean mEnterAnimationPending;
6446
6447 // Currently running animation.
6448 boolean mAnimating;
6449 boolean mLocalAnimating;
6450 Animation mAnimation;
6451 boolean mAnimationIsEntrance;
6452 boolean mHasTransformation;
6453 boolean mHasLocalTransformation;
6454 final Transformation mTransformation = new Transformation();
6455
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006456 // If a window showing a wallpaper: the requested offset for the
6457 // wallpaper; if a wallpaper window: the currently applied offset.
6458 float mWallpaperX = -1;
6459 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006460
6461 // If a window showing a wallpaper: what fraction of the offset
6462 // range corresponds to a full virtual screen.
6463 float mWallpaperXStep = -1;
6464 float mWallpaperYStep = -1;
6465
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006466 // Wallpaper windows: pixels offset based on above variables.
6467 int mXOffset;
6468 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 // This is set after IWindowSession.relayout() has been called at
6471 // least once for the window. It allows us to detect the situation
6472 // where we don't yet have a surface, but should have one soon, so
6473 // we can give the window focus before waiting for the relayout.
6474 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006476 // This is set after the Surface has been created but before the
6477 // window has been drawn. During this time the surface is hidden.
6478 boolean mDrawPending;
6479
6480 // This is set after the window has finished drawing for the first
6481 // time but before its surface is shown. The surface will be
6482 // displayed when the next layout is run.
6483 boolean mCommitDrawPending;
6484
6485 // This is set during the time after the window's drawing has been
6486 // committed, and before its surface is actually shown. It is used
6487 // to delay showing the surface until all windows in a token are ready
6488 // to be shown.
6489 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491 // Set when the window has been shown in the screen the first time.
6492 boolean mHasDrawn;
6493
6494 // Currently running an exit animation?
6495 boolean mExiting;
6496
6497 // Currently on the mDestroySurface list?
6498 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 // Completely remove from window manager after exit animation?
6501 boolean mRemoveOnExit;
6502
6503 // Set when the orientation is changing and this window has not yet
6504 // been updated for the new orientation.
6505 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 // Is this window now (or just being) removed?
6508 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006509
Dianne Hackborn16064f92010-03-25 00:47:24 -07006510 // For debugging, this is the last information given to the surface flinger.
6511 boolean mSurfaceShown;
6512 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6513 int mSurfaceLayer;
6514 float mSurfaceAlpha;
6515
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006516 // Input channel
6517 InputChannel mInputChannel;
6518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 WindowState(Session s, IWindow c, WindowToken token,
6520 WindowState attachedWindow, WindowManager.LayoutParams a,
6521 int viewVisibility) {
6522 mSession = s;
6523 mClient = c;
6524 mToken = token;
6525 mAttrs.copyFrom(a);
6526 mViewVisibility = viewVisibility;
6527 DeathRecipient deathRecipient = new DeathRecipient();
6528 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006529 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006530 TAG, "Window " + this + " client=" + c.asBinder()
6531 + " token=" + token + " (" + mAttrs.token + ")");
6532 try {
6533 c.asBinder().linkToDeath(deathRecipient, 0);
6534 } catch (RemoteException e) {
6535 mDeathRecipient = null;
6536 mAttachedWindow = null;
6537 mLayoutAttached = false;
6538 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006539 mIsWallpaper = false;
6540 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006541 mBaseLayer = 0;
6542 mSubLayer = 0;
6543 return;
6544 }
6545 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006547 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6548 mAttrs.type <= LAST_SUB_WINDOW)) {
6549 // The multiplier here is to reserve space for multiple
6550 // windows in the same type layer.
6551 mBaseLayer = mPolicy.windowTypeToLayerLw(
6552 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6553 + TYPE_LAYER_OFFSET;
6554 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6555 mAttachedWindow = attachedWindow;
6556 mAttachedWindow.mChildWindows.add(this);
6557 mLayoutAttached = mAttrs.type !=
6558 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6559 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6560 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006561 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6562 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006563 } else {
6564 // The multiplier here is to reserve space for multiple
6565 // windows in the same type layer.
6566 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6567 * TYPE_LAYER_MULTIPLIER
6568 + TYPE_LAYER_OFFSET;
6569 mSubLayer = 0;
6570 mAttachedWindow = null;
6571 mLayoutAttached = false;
6572 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6573 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006574 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6575 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006576 }
6577
6578 WindowState appWin = this;
6579 while (appWin.mAttachedWindow != null) {
6580 appWin = mAttachedWindow;
6581 }
6582 WindowToken appToken = appWin.mToken;
6583 while (appToken.appWindowToken == null) {
6584 WindowToken parent = mTokenMap.get(appToken.token);
6585 if (parent == null || appToken == parent) {
6586 break;
6587 }
6588 appToken = parent;
6589 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006590 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 mAppToken = appToken.appWindowToken;
6592
6593 mSurface = null;
6594 mRequestedWidth = 0;
6595 mRequestedHeight = 0;
6596 mLastRequestedWidth = 0;
6597 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006598 mXOffset = 0;
6599 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006600 mLayer = 0;
6601 mAnimLayer = 0;
6602 mLastLayer = 0;
6603 }
6604
6605 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 TAG, "Attaching " + this + " token=" + mToken
6608 + ", list=" + mToken.windows);
6609 mSession.windowAddedLocked();
6610 }
6611
6612 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6613 mHaveFrame = true;
6614
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006615 final Rect container = mContainingFrame;
6616 container.set(pf);
6617
6618 final Rect display = mDisplayFrame;
6619 display.set(df);
6620
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006621 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006622 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006623 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6624 display.intersect(mCompatibleScreenFrame);
6625 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006626 }
6627
6628 final int pw = container.right - container.left;
6629 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630
6631 int w,h;
6632 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6633 w = mAttrs.width < 0 ? pw : mAttrs.width;
6634 h = mAttrs.height< 0 ? ph : mAttrs.height;
6635 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006636 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6637 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006638 }
Romain Guy06882f82009-06-10 13:36:04 -07006639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 final Rect content = mContentFrame;
6641 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006643 final Rect visible = mVisibleFrame;
6644 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006646 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006647 final int fw = frame.width();
6648 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6651 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6652
6653 Gravity.apply(mAttrs.gravity, w, h, container,
6654 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6655 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6656
6657 //System.out.println("Out: " + mFrame);
6658
6659 // Now make sure the window fits in the overall display.
6660 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006662 // Make sure the content and visible frames are inside of the
6663 // final window frame.
6664 if (content.left < frame.left) content.left = frame.left;
6665 if (content.top < frame.top) content.top = frame.top;
6666 if (content.right > frame.right) content.right = frame.right;
6667 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6668 if (visible.left < frame.left) visible.left = frame.left;
6669 if (visible.top < frame.top) visible.top = frame.top;
6670 if (visible.right > frame.right) visible.right = frame.right;
6671 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 final Rect contentInsets = mContentInsets;
6674 contentInsets.left = content.left-frame.left;
6675 contentInsets.top = content.top-frame.top;
6676 contentInsets.right = frame.right-content.right;
6677 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 final Rect visibleInsets = mVisibleInsets;
6680 visibleInsets.left = visible.left-frame.left;
6681 visibleInsets.top = visible.top-frame.top;
6682 visibleInsets.right = frame.right-visible.right;
6683 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006684
Dianne Hackborn284ac932009-08-28 10:34:25 -07006685 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6686 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006687 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006688 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 if (localLOGV) {
6691 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6692 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006693 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 + mRequestedWidth + ", mRequestedheight="
6695 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6696 + "): frame=" + mFrame.toShortString()
6697 + " ci=" + contentInsets.toShortString()
6698 + " vi=" + visibleInsets.toShortString());
6699 //}
6700 }
6701 }
Romain Guy06882f82009-06-10 13:36:04 -07006702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 public Rect getFrameLw() {
6704 return mFrame;
6705 }
6706
6707 public Rect getShownFrameLw() {
6708 return mShownFrame;
6709 }
6710
6711 public Rect getDisplayFrameLw() {
6712 return mDisplayFrame;
6713 }
6714
6715 public Rect getContentFrameLw() {
6716 return mContentFrame;
6717 }
6718
6719 public Rect getVisibleFrameLw() {
6720 return mVisibleFrame;
6721 }
6722
6723 public boolean getGivenInsetsPendingLw() {
6724 return mGivenInsetsPending;
6725 }
6726
6727 public Rect getGivenContentInsetsLw() {
6728 return mGivenContentInsets;
6729 }
Romain Guy06882f82009-06-10 13:36:04 -07006730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 public Rect getGivenVisibleInsetsLw() {
6732 return mGivenVisibleInsets;
6733 }
Romain Guy06882f82009-06-10 13:36:04 -07006734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006735 public WindowManager.LayoutParams getAttrs() {
6736 return mAttrs;
6737 }
6738
6739 public int getSurfaceLayer() {
6740 return mLayer;
6741 }
Romain Guy06882f82009-06-10 13:36:04 -07006742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 public IApplicationToken getAppToken() {
6744 return mAppToken != null ? mAppToken.appToken : null;
6745 }
Jeff Brown349703e2010-06-22 01:27:15 -07006746
6747 public long getInputDispatchingTimeoutNanos() {
6748 return mAppToken != null
6749 ? mAppToken.inputDispatchingTimeoutNanos
6750 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006752
6753 public boolean hasAppShownWindows() {
6754 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6755 }
6756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006758 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006759 TAG, "Setting animation in " + this + ": " + anim);
6760 mAnimating = false;
6761 mLocalAnimating = false;
6762 mAnimation = anim;
6763 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6764 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6765 }
6766
6767 public void clearAnimation() {
6768 if (mAnimation != null) {
6769 mAnimating = true;
6770 mLocalAnimating = false;
6771 mAnimation = null;
6772 }
6773 }
Romain Guy06882f82009-06-10 13:36:04 -07006774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006775 Surface createSurfaceLocked() {
6776 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006777 mReportDestroySurface = false;
6778 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 mDrawPending = true;
6780 mCommitDrawPending = false;
6781 mReadyToShow = false;
6782 if (mAppToken != null) {
6783 mAppToken.allDrawn = false;
6784 }
6785
6786 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006787 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 flags |= Surface.PUSH_BUFFERS;
6789 }
6790
6791 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6792 flags |= Surface.SECURE;
6793 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006794 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 TAG, "Creating surface in session "
6796 + mSession.mSurfaceSession + " window " + this
6797 + " w=" + mFrame.width()
6798 + " h=" + mFrame.height() + " format="
6799 + mAttrs.format + " flags=" + flags);
6800
6801 int w = mFrame.width();
6802 int h = mFrame.height();
6803 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
6804 // for a scaled surface, we always want the requested
6805 // size.
6806 w = mRequestedWidth;
6807 h = mRequestedHeight;
6808 }
6809
Romain Guy9825ec62009-10-01 00:58:09 -07006810 // Something is wrong and SurfaceFlinger will not like this,
6811 // try to revert to sane values
6812 if (w <= 0) w = 1;
6813 if (h <= 0) h = 1;
6814
Dianne Hackborn16064f92010-03-25 00:47:24 -07006815 mSurfaceShown = false;
6816 mSurfaceLayer = 0;
6817 mSurfaceAlpha = 1;
6818 mSurfaceX = 0;
6819 mSurfaceY = 0;
6820 mSurfaceW = w;
6821 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 try {
6823 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07006824 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08006825 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006827 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006828 + mSurface + " IN SESSION "
6829 + mSession.mSurfaceSession
6830 + ": pid=" + mSession.mPid + " format="
6831 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006832 + Integer.toHexString(flags)
6833 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006835 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006836 reclaimSomeSurfaceMemoryLocked(this, "create");
6837 return null;
6838 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006839 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840 return null;
6841 }
Romain Guy06882f82009-06-10 13:36:04 -07006842
Joe Onorato8a9b2202010-02-26 18:56:32 -08006843 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006844 TAG, "Got surface: " + mSurface
6845 + ", set left=" + mFrame.left + " top=" + mFrame.top
6846 + ", animLayer=" + mAnimLayer);
6847 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006848 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006849 if (SHOW_TRANSACTIONS) logSurface(this,
6850 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
6851 mFrame.width() + "x" + mFrame.height() + "), layer=" +
6852 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 }
6854 Surface.openTransaction();
6855 try {
6856 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07006857 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07006858 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07006859 mSurface.setPosition(mSurfaceX, mSurfaceY);
6860 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006862 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 mSurface.hide();
6864 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006865 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 mSurface.setFlags(Surface.SURFACE_DITHER,
6867 Surface.SURFACE_DITHER);
6868 }
6869 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006870 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 reclaimSomeSurfaceMemoryLocked(this, "create-init");
6872 }
6873 mLastHidden = true;
6874 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006875 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 Surface.closeTransaction();
6877 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006878 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879 TAG, "Created surface " + this);
6880 }
6881 return mSurface;
6882 }
Romain Guy06882f82009-06-10 13:36:04 -07006883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006884 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 if (mAppToken != null && this == mAppToken.startingWindow) {
6886 mAppToken.startingDisplayed = false;
6887 }
Romain Guy06882f82009-06-10 13:36:04 -07006888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006890 mDrawPending = false;
6891 mCommitDrawPending = false;
6892 mReadyToShow = false;
6893
6894 int i = mChildWindows.size();
6895 while (i > 0) {
6896 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006897 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006898 c.mAttachedHidden = true;
6899 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006900
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006901 if (mReportDestroySurface) {
6902 mReportDestroySurface = false;
6903 mSurfacePendingDestroy = true;
6904 try {
6905 mClient.dispatchGetNewSurface();
6906 // We'll really destroy on the next time around.
6907 return;
6908 } catch (RemoteException e) {
6909 }
6910 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006913 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006914 RuntimeException e = null;
6915 if (!HIDE_STACK_CRAWLS) {
6916 e = new RuntimeException();
6917 e.fillInStackTrace();
6918 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006919 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006920 + mSurface + ", session " + mSession, e);
6921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006923 RuntimeException e = null;
6924 if (!HIDE_STACK_CRAWLS) {
6925 e = new RuntimeException();
6926 e.fillInStackTrace();
6927 }
6928 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006930 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006932 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 + " surface " + mSurface + " session " + mSession
6934 + ": " + e.toString());
6935 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006936
Dianne Hackborn16064f92010-03-25 00:47:24 -07006937 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006938 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 }
6940 }
6941
6942 boolean finishDrawingLocked() {
6943 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006944 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 TAG, "finishDrawingLocked: " + mSurface);
6946 mCommitDrawPending = true;
6947 mDrawPending = false;
6948 return true;
6949 }
6950 return false;
6951 }
6952
6953 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006954 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006955 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006957 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006958 }
6959 mCommitDrawPending = false;
6960 mReadyToShow = true;
6961 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
6962 final AppWindowToken atoken = mAppToken;
6963 if (atoken == null || atoken.allDrawn || starting) {
6964 performShowLocked();
6965 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006966 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006967 }
6968
6969 // This must be called while inside a transaction.
6970 boolean performShowLocked() {
6971 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006972 RuntimeException e = null;
6973 if (!HIDE_STACK_CRAWLS) {
6974 e = new RuntimeException();
6975 e.fillInStackTrace();
6976 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006977 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006978 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
6979 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
6980 }
6981 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006982 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
6983 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006984 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 + " during animation: policyVis=" + mPolicyVisibility
6986 + " attHidden=" + mAttachedHidden
6987 + " tok.hiddenRequested="
6988 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07006989 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 + (mAppToken != null ? mAppToken.hidden : false)
6991 + " animating=" + mAnimating
6992 + " tok animating="
6993 + (mAppToken != null ? mAppToken.animating : false));
6994 if (!showSurfaceRobustlyLocked(this)) {
6995 return false;
6996 }
6997 mLastAlpha = -1;
6998 mHasDrawn = true;
6999 mLastHidden = false;
7000 mReadyToShow = false;
7001 enableScreenIfNeededLocked();
7002
7003 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 int i = mChildWindows.size();
7006 while (i > 0) {
7007 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007008 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007009 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007011 if (c.mSurface != null) {
7012 c.performShowLocked();
7013 // It hadn't been shown, which means layout not
7014 // performed on it, so now we want to make sure to
7015 // do a layout. If called from within the transaction
7016 // loop, this will cause it to restart with a new
7017 // layout.
7018 mLayoutNeeded = true;
7019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007020 }
7021 }
Romain Guy06882f82009-06-10 13:36:04 -07007022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 if (mAttrs.type != TYPE_APPLICATION_STARTING
7024 && mAppToken != null) {
7025 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007026
Dianne Hackborn248b1882009-09-16 16:46:44 -07007027 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007028 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007029 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007031 // If this initial window is animating, stop it -- we
7032 // will do an animation to reveal it from behind the
7033 // starting window, so there is no need for it to also
7034 // be doing its own stuff.
7035 if (mAnimation != null) {
7036 mAnimation = null;
7037 // Make sure we clean up the animation.
7038 mAnimating = true;
7039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 mFinishedStarting.add(mAppToken);
7041 mH.sendEmptyMessage(H.FINISHED_STARTING);
7042 }
7043 mAppToken.updateReportedVisibilityLocked();
7044 }
7045 }
7046 return true;
7047 }
Romain Guy06882f82009-06-10 13:36:04 -07007048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007049 // This must be called while inside a transaction. Returns true if
7050 // there is more animation to run.
7051 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007052 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007055 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7056 mHasTransformation = true;
7057 mHasLocalTransformation = true;
7058 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007059 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 TAG, "Starting animation in " + this +
7061 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7062 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7063 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7064 mAnimation.setStartTime(currentTime);
7065 mLocalAnimating = true;
7066 mAnimating = true;
7067 }
7068 mTransformation.clear();
7069 final boolean more = mAnimation.getTransformation(
7070 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007071 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007072 TAG, "Stepped animation in " + this +
7073 ": more=" + more + ", xform=" + mTransformation);
7074 if (more) {
7075 // we're not done!
7076 return true;
7077 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007078 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 TAG, "Finished animation in " + this +
7080 " @ " + currentTime);
7081 mAnimation = null;
7082 //WindowManagerService.this.dump();
7083 }
7084 mHasLocalTransformation = false;
7085 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007086 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 // When our app token is animating, we kind-of pretend like
7088 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7089 // part of this check means that we will only do this if
7090 // our window is not currently exiting, or it is not
7091 // locally animating itself. The idea being that one that
7092 // is exiting and doing a local animation should be removed
7093 // once that animation is done.
7094 mAnimating = true;
7095 mHasTransformation = true;
7096 mTransformation.clear();
7097 return false;
7098 } else if (mHasTransformation) {
7099 // Little trick to get through the path below to act like
7100 // we have finished an animation.
7101 mAnimating = true;
7102 } else if (isAnimating()) {
7103 mAnimating = true;
7104 }
7105 } else if (mAnimation != null) {
7106 // If the display is frozen, and there is a pending animation,
7107 // clear it and make sure we run the cleanup code.
7108 mAnimating = true;
7109 mLocalAnimating = true;
7110 mAnimation = null;
7111 }
Romain Guy06882f82009-06-10 13:36:04 -07007112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007113 if (!mAnimating && !mLocalAnimating) {
7114 return false;
7115 }
7116
Joe Onorato8a9b2202010-02-26 18:56:32 -08007117 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007118 TAG, "Animation done in " + this + ": exiting=" + mExiting
7119 + ", reportedVisible="
7120 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 mAnimating = false;
7123 mLocalAnimating = false;
7124 mAnimation = null;
7125 mAnimLayer = mLayer;
7126 if (mIsImWindow) {
7127 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007128 } else if (mIsWallpaper) {
7129 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007130 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007131 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 + " anim layer: " + mAnimLayer);
7133 mHasTransformation = false;
7134 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007135 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7136 if (DEBUG_VISIBILITY) {
7137 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7138 + mPolicyVisibilityAfterAnim);
7139 }
7140 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7141 if (!mPolicyVisibility) {
7142 if (mCurrentFocus == this) {
7143 mFocusMayChange = true;
7144 }
7145 // Window is no longer visible -- make sure if we were waiting
7146 // for it to be displayed before enabling the display, that
7147 // we allow the display to be enabled now.
7148 enableScreenIfNeededLocked();
7149 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007151 mTransformation.clear();
7152 if (mHasDrawn
7153 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7154 && mAppToken != null
7155 && mAppToken.firstWindowDrawn
7156 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007157 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 + mToken + ": first real window done animating");
7159 mFinishedStarting.add(mAppToken);
7160 mH.sendEmptyMessage(H.FINISHED_STARTING);
7161 }
Romain Guy06882f82009-06-10 13:36:04 -07007162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 finishExit();
7164
7165 if (mAppToken != null) {
7166 mAppToken.updateReportedVisibilityLocked();
7167 }
7168
7169 return false;
7170 }
7171
7172 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007173 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007174 TAG, "finishExit in " + this
7175 + ": exiting=" + mExiting
7176 + " remove=" + mRemoveOnExit
7177 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007179 final int N = mChildWindows.size();
7180 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007181 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 }
Romain Guy06882f82009-06-10 13:36:04 -07007183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 if (!mExiting) {
7185 return;
7186 }
Romain Guy06882f82009-06-10 13:36:04 -07007187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 if (isWindowAnimating()) {
7189 return;
7190 }
7191
Joe Onorato8a9b2202010-02-26 18:56:32 -08007192 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 TAG, "Exit animation finished in " + this
7194 + ": remove=" + mRemoveOnExit);
7195 if (mSurface != null) {
7196 mDestroySurface.add(this);
7197 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007198 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007199 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007200 try {
7201 mSurface.hide();
7202 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007203 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 }
7205 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 }
7207 mExiting = false;
7208 if (mRemoveOnExit) {
7209 mPendingRemove.add(this);
7210 mRemoveOnExit = false;
7211 }
7212 }
Romain Guy06882f82009-06-10 13:36:04 -07007213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7215 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7216 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7217 if (dtdx < -.000001f || dtdx > .000001f) return false;
7218 if (dsdy < -.000001f || dsdy > .000001f) return false;
7219 return true;
7220 }
Romain Guy06882f82009-06-10 13:36:04 -07007221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007222 void computeShownFrameLocked() {
7223 final boolean selfTransformation = mHasLocalTransformation;
7224 Transformation attachedTransformation =
7225 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7226 ? mAttachedWindow.mTransformation : null;
7227 Transformation appTransformation =
7228 (mAppToken != null && mAppToken.hasTransformation)
7229 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007230
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007231 // Wallpapers are animated based on the "real" window they
7232 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007233 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007234 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007235 if (mWallpaperTarget.mHasLocalTransformation &&
7236 mWallpaperTarget.mAnimation != null &&
7237 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007238 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007239 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007240 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007241 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007242 }
7243 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007244 mWallpaperTarget.mAppToken.hasTransformation &&
7245 mWallpaperTarget.mAppToken.animation != null &&
7246 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007247 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007248 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007249 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007250 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007251 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007252 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007254 if (selfTransformation || attachedTransformation != null
7255 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007256 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 final Rect frame = mFrame;
7258 final float tmpFloats[] = mTmpFloats;
7259 final Matrix tmpMatrix = mTmpMatrix;
7260
7261 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007262 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007263 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007264 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007265 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007266 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007268 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007269 }
7270 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007271 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007272 }
7273
7274 // "convert" it into SurfaceFlinger's format
7275 // (a 2x2 matrix + an offset)
7276 // Here we must not transform the position of the surface
7277 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007278 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007280 tmpMatrix.getValues(tmpFloats);
7281 mDsDx = tmpFloats[Matrix.MSCALE_X];
7282 mDtDx = tmpFloats[Matrix.MSKEW_X];
7283 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7284 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007285 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7286 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 int w = frame.width();
7288 int h = frame.height();
7289 mShownFrame.set(x, y, x+w, y+h);
7290
7291 // Now set the alpha... but because our current hardware
7292 // can't do alpha transformation on a non-opaque surface,
7293 // turn it off if we are running an animation that is also
7294 // transforming since it is more important to have that
7295 // animation be smooth.
7296 mShownAlpha = mAlpha;
7297 if (!mLimitedAlphaCompositing
7298 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7299 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7300 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007301 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007302 if (selfTransformation) {
7303 mShownAlpha *= mTransformation.getAlpha();
7304 }
7305 if (attachedTransformation != null) {
7306 mShownAlpha *= attachedTransformation.getAlpha();
7307 }
7308 if (appTransformation != null) {
7309 mShownAlpha *= appTransformation.getAlpha();
7310 }
7311 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007312 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 }
Romain Guy06882f82009-06-10 13:36:04 -07007314
Joe Onorato8a9b2202010-02-26 18:56:32 -08007315 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007316 TAG, "Continuing animation in " + this +
7317 ": " + mShownFrame +
7318 ", alpha=" + mTransformation.getAlpha());
7319 return;
7320 }
Romain Guy06882f82009-06-10 13:36:04 -07007321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007322 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007323 if (mXOffset != 0 || mYOffset != 0) {
7324 mShownFrame.offset(mXOffset, mYOffset);
7325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 mShownAlpha = mAlpha;
7327 mDsDx = 1;
7328 mDtDx = 0;
7329 mDsDy = 0;
7330 mDtDy = 1;
7331 }
Romain Guy06882f82009-06-10 13:36:04 -07007332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007333 /**
7334 * Is this window visible? It is not visible if there is no
7335 * surface, or we are in the process of running an exit animation
7336 * that will remove the surface, or its app token has been hidden.
7337 */
7338 public boolean isVisibleLw() {
7339 final AppWindowToken atoken = mAppToken;
7340 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7341 && (atoken == null || !atoken.hiddenRequested)
7342 && !mExiting && !mDestroying;
7343 }
7344
7345 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007346 * Like {@link #isVisibleLw}, but also counts a window that is currently
7347 * "hidden" behind the keyguard as visible. This allows us to apply
7348 * things like window flags that impact the keyguard.
7349 * XXX I am starting to think we need to have ANOTHER visibility flag
7350 * for this "hidden behind keyguard" state rather than overloading
7351 * mPolicyVisibility. Ungh.
7352 */
7353 public boolean isVisibleOrBehindKeyguardLw() {
7354 final AppWindowToken atoken = mAppToken;
7355 return mSurface != null && !mAttachedHidden
7356 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007357 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007358 && !mExiting && !mDestroying;
7359 }
7360
7361 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362 * Is this window visible, ignoring its app token? It is not visible
7363 * if there is no surface, or we are in the process of running an exit animation
7364 * that will remove the surface.
7365 */
7366 public boolean isWinVisibleLw() {
7367 final AppWindowToken atoken = mAppToken;
7368 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7369 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7370 && !mExiting && !mDestroying;
7371 }
7372
7373 /**
7374 * The same as isVisible(), but follows the current hidden state of
7375 * the associated app token, not the pending requested hidden state.
7376 */
7377 boolean isVisibleNow() {
7378 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007379 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 }
7381
7382 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007383 * Can this window possibly be a drag/drop target? The test here is
7384 * a combination of the above "visible now" with the check that the
7385 * Input Manager uses when discarding windows from input consideration.
7386 */
7387 boolean isPotentialDragTarget() {
7388 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7389 }
7390
7391 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 * Same as isVisible(), but we also count it as visible between the
7393 * call to IWindowSession.add() and the first relayout().
7394 */
7395 boolean isVisibleOrAdding() {
7396 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007397 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007398 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7399 && mPolicyVisibility && !mAttachedHidden
7400 && (atoken == null || !atoken.hiddenRequested)
7401 && !mExiting && !mDestroying;
7402 }
7403
7404 /**
7405 * Is this window currently on-screen? It is on-screen either if it
7406 * is visible or it is currently running an animation before no longer
7407 * being visible.
7408 */
7409 boolean isOnScreen() {
7410 final AppWindowToken atoken = mAppToken;
7411 if (atoken != null) {
7412 return mSurface != null && mPolicyVisibility && !mDestroying
7413 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007414 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007415 } else {
7416 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007417 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 }
7419 }
Romain Guy06882f82009-06-10 13:36:04 -07007420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007421 /**
7422 * Like isOnScreen(), but we don't return true if the window is part
7423 * of a transition that has not yet been started.
7424 */
7425 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007426 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007427 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007428 return false;
7429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007430 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007431 final boolean animating = atoken != null
7432 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007433 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007434 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7435 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007436 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
7438
7439 /** Is the window or its container currently animating? */
7440 boolean isAnimating() {
7441 final WindowState attached = mAttachedWindow;
7442 final AppWindowToken atoken = mAppToken;
7443 return mAnimation != null
7444 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007445 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007446 (atoken.animation != null
7447 || atoken.inPendingTransaction));
7448 }
7449
7450 /** Is this window currently animating? */
7451 boolean isWindowAnimating() {
7452 return mAnimation != null;
7453 }
7454
7455 /**
7456 * Like isOnScreen, but returns false if the surface hasn't yet
7457 * been drawn.
7458 */
7459 public boolean isDisplayedLw() {
7460 final AppWindowToken atoken = mAppToken;
7461 return mSurface != null && mPolicyVisibility && !mDestroying
7462 && !mDrawPending && !mCommitDrawPending
7463 && ((!mAttachedHidden &&
7464 (atoken == null || !atoken.hiddenRequested))
7465 || mAnimating);
7466 }
7467
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007468 /**
7469 * Returns true if the window has a surface that it has drawn a
7470 * complete UI in to.
7471 */
7472 public boolean isDrawnLw() {
7473 final AppWindowToken atoken = mAppToken;
7474 return mSurface != null && !mDestroying
7475 && !mDrawPending && !mCommitDrawPending;
7476 }
7477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007478 public boolean fillsScreenLw(int screenWidth, int screenHeight,
7479 boolean shownFrame, boolean onlyOpaque) {
7480 if (mSurface == null) {
7481 return false;
7482 }
7483 if (mAppToken != null && !mAppToken.appFullscreen) {
7484 return false;
7485 }
7486 if (onlyOpaque && mAttrs.format != PixelFormat.OPAQUE) {
7487 return false;
7488 }
7489 final Rect frame = shownFrame ? mShownFrame : mFrame;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007490
7491 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
7492 return frame.left <= mCompatibleScreenFrame.left &&
7493 frame.top <= mCompatibleScreenFrame.top &&
7494 frame.right >= mCompatibleScreenFrame.right &&
7495 frame.bottom >= mCompatibleScreenFrame.bottom;
7496 } else {
Joe Onorato93056472010-09-10 10:30:46 -04007497 if ((mAttrs.flags & FLAG_FULLSCREEN) != 0) {
7498 return true;
7499 }
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007500 return frame.left <= 0 && frame.top <= 0
7501 && frame.right >= screenWidth
7502 && frame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504 }
Romain Guy06882f82009-06-10 13:36:04 -07007505
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007506 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007507 * Return true if the window is opaque and fully drawn. This indicates
7508 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007509 */
7510 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007511 return (mAttrs.format == PixelFormat.OPAQUE
7512 || mAttrs.type == TYPE_WALLPAPER)
7513 && mSurface != null && mAnimation == null
7514 && (mAppToken == null || mAppToken.animation == null)
7515 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007516 }
7517
7518 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7519 return
7520 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007521 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7522 // only if it's visible
7523 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007524 // and only if the application fills the compatible screen
7525 mFrame.left <= mCompatibleScreenFrame.left &&
7526 mFrame.top <= mCompatibleScreenFrame.top &&
7527 mFrame.right >= mCompatibleScreenFrame.right &&
7528 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007529 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007530 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007531 }
7532
7533 boolean isFullscreen(int screenWidth, int screenHeight) {
7534 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007535 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 }
7537
7538 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007539 disposeInputChannel();
7540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 if (mAttachedWindow != null) {
7542 mAttachedWindow.mChildWindows.remove(this);
7543 }
7544 destroySurfaceLocked();
7545 mSession.windowRemovedLocked();
7546 try {
7547 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7548 } catch (RuntimeException e) {
7549 // Ignore if it has already been removed (usually because
7550 // we are doing this as part of processing a death note.)
7551 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007552 }
7553
7554 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007555 if (mInputChannel != null) {
7556 mInputManager.unregisterInputChannel(mInputChannel);
7557
7558 mInputChannel.dispose();
7559 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007561 }
7562
7563 private class DeathRecipient implements IBinder.DeathRecipient {
7564 public void binderDied() {
7565 try {
7566 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007567 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007568 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007569 if (win != null) {
7570 removeWindowLocked(mSession, win);
7571 }
7572 }
7573 } catch (IllegalArgumentException ex) {
7574 // This will happen if the window has already been
7575 // removed.
7576 }
7577 }
7578 }
7579
7580 /** Returns true if this window desires key events. */
7581 public final boolean canReceiveKeys() {
7582 return isVisibleOrAdding()
7583 && (mViewVisibility == View.VISIBLE)
7584 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7585 }
7586
7587 public boolean hasDrawnLw() {
7588 return mHasDrawn;
7589 }
7590
7591 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007592 return showLw(doAnimation, true);
7593 }
7594
7595 boolean showLw(boolean doAnimation, boolean requestAnim) {
7596 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7597 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007598 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007599 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007600 if (doAnimation) {
7601 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7602 + mPolicyVisibility + " mAnimation=" + mAnimation);
7603 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7604 doAnimation = false;
7605 } else if (mPolicyVisibility && mAnimation == null) {
7606 // Check for the case where we are currently visible and
7607 // not animating; we do not want to do animation at such a
7608 // point to become visible when we already are.
7609 doAnimation = false;
7610 }
7611 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007612 mPolicyVisibility = true;
7613 mPolicyVisibilityAfterAnim = true;
7614 if (doAnimation) {
7615 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7616 }
7617 if (requestAnim) {
7618 requestAnimationLocked(0);
7619 }
7620 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007621 }
7622
7623 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007624 return hideLw(doAnimation, true);
7625 }
7626
7627 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007628 if (doAnimation) {
7629 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7630 doAnimation = false;
7631 }
7632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7634 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007635 if (!current) {
7636 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007638 if (doAnimation) {
7639 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7640 if (mAnimation == null) {
7641 doAnimation = false;
7642 }
7643 }
7644 if (doAnimation) {
7645 mPolicyVisibilityAfterAnim = false;
7646 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007647 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007648 mPolicyVisibilityAfterAnim = false;
7649 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007650 // Window is no longer visible -- make sure if we were waiting
7651 // for it to be displayed before enabling the display, that
7652 // we allow the display to be enabled now.
7653 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007654 if (mCurrentFocus == this) {
7655 mFocusMayChange = true;
7656 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007657 }
7658 if (requestAnim) {
7659 requestAnimationLocked(0);
7660 }
7661 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 }
7663
7664 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007665 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7666 pw.print(" mClient="); pw.println(mClient.asBinder());
7667 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7668 if (mAttachedWindow != null || mLayoutAttached) {
7669 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7670 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7671 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007672 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7673 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7674 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007675 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7676 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007677 }
7678 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7679 pw.print(" mSubLayer="); pw.print(mSubLayer);
7680 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7681 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7682 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7683 pw.print("="); pw.print(mAnimLayer);
7684 pw.print(" mLastLayer="); pw.println(mLastLayer);
7685 if (mSurface != null) {
7686 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007687 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7688 pw.print(" layer="); pw.print(mSurfaceLayer);
7689 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7690 pw.print(" rect=("); pw.print(mSurfaceX);
7691 pw.print(","); pw.print(mSurfaceY);
7692 pw.print(") "); pw.print(mSurfaceW);
7693 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007694 }
7695 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7696 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7697 if (mAppToken != null) {
7698 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7699 }
7700 if (mTargetAppToken != null) {
7701 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7702 }
7703 pw.print(prefix); pw.print("mViewVisibility=0x");
7704 pw.print(Integer.toHexString(mViewVisibility));
7705 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007706 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7707 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007708 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7709 pw.print(prefix); pw.print("mPolicyVisibility=");
7710 pw.print(mPolicyVisibility);
7711 pw.print(" mPolicyVisibilityAfterAnim=");
7712 pw.print(mPolicyVisibilityAfterAnim);
7713 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7714 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007715 if (!mRelayoutCalled) {
7716 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7717 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007718 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007719 pw.print(" h="); pw.print(mRequestedHeight);
7720 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007721 if (mXOffset != 0 || mYOffset != 0) {
7722 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7723 pw.print(" y="); pw.println(mYOffset);
7724 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007725 pw.print(prefix); pw.print("mGivenContentInsets=");
7726 mGivenContentInsets.printShortString(pw);
7727 pw.print(" mGivenVisibleInsets=");
7728 mGivenVisibleInsets.printShortString(pw);
7729 pw.println();
7730 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7731 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7732 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7733 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007734 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007735 pw.print(prefix); pw.print("mShownFrame=");
7736 mShownFrame.printShortString(pw);
7737 pw.print(" last="); mLastShownFrame.printShortString(pw);
7738 pw.println();
7739 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7740 pw.print(" last="); mLastFrame.printShortString(pw);
7741 pw.println();
7742 pw.print(prefix); pw.print("mContainingFrame=");
7743 mContainingFrame.printShortString(pw);
7744 pw.print(" mDisplayFrame=");
7745 mDisplayFrame.printShortString(pw);
7746 pw.println();
7747 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7748 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7749 pw.println();
7750 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7751 pw.print(" last="); mLastContentInsets.printShortString(pw);
7752 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7753 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7754 pw.println();
7755 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7756 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7757 pw.print(" mAlpha="); pw.print(mAlpha);
7758 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7759 }
7760 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7761 || mAnimation != null) {
7762 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7763 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7764 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7765 pw.print(" mAnimation="); pw.println(mAnimation);
7766 }
7767 if (mHasTransformation || mHasLocalTransformation) {
7768 pw.print(prefix); pw.print("XForm: has=");
7769 pw.print(mHasTransformation);
7770 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7771 pw.print(" "); mTransformation.printShortString(pw);
7772 pw.println();
7773 }
7774 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7775 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7776 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7777 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7778 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7779 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7780 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7781 pw.print(" mDestroying="); pw.print(mDestroying);
7782 pw.print(" mRemoved="); pw.println(mRemoved);
7783 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007784 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007785 pw.print(prefix); pw.print("mOrientationChanging=");
7786 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007787 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7788 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007789 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007790 if (mHScale != 1 || mVScale != 1) {
7791 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7792 pw.print(" mVScale="); pw.println(mVScale);
7793 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007794 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007795 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7796 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7797 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007798 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7799 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7800 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007803
7804 String makeInputChannelName() {
7805 return Integer.toHexString(System.identityHashCode(this))
7806 + " " + mAttrs.getTitle();
7807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808
7809 @Override
7810 public String toString() {
7811 return "Window{"
7812 + Integer.toHexString(System.identityHashCode(this))
7813 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7814 }
7815 }
Romain Guy06882f82009-06-10 13:36:04 -07007816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 // -------------------------------------------------------------
7818 // Window Token State
7819 // -------------------------------------------------------------
7820
7821 class WindowToken {
7822 // The actual token.
7823 final IBinder token;
7824
7825 // The type of window this token is for, as per WindowManager.LayoutParams.
7826 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07007827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007828 // Set if this token was explicitly added by a client, so should
7829 // not be removed when all windows are removed.
7830 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07007831
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007832 // For printing.
7833 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07007834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 // If this is an AppWindowToken, this is non-null.
7836 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07007837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 // All of the windows associated with this token.
7839 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
7840
7841 // Is key dispatching paused for this token?
7842 boolean paused = false;
7843
7844 // Should this token's windows be hidden?
7845 boolean hidden;
7846
7847 // Temporary for finding which tokens no longer have visible windows.
7848 boolean hasVisible;
7849
Dianne Hackborna8f60182009-09-01 19:01:50 -07007850 // Set to true when this token is in a pending transaction where it
7851 // will be shown.
7852 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007853
Dianne Hackborna8f60182009-09-01 19:01:50 -07007854 // Set to true when this token is in a pending transaction where it
7855 // will be hidden.
7856 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007857
Dianne Hackborna8f60182009-09-01 19:01:50 -07007858 // Set to true when this token is in a pending transaction where its
7859 // windows will be put to the bottom of the list.
7860 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007861
Dianne Hackborna8f60182009-09-01 19:01:50 -07007862 // Set to true when this token is in a pending transaction where its
7863 // windows will be put to the top of the list.
7864 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007866 WindowToken(IBinder _token, int type, boolean _explicit) {
7867 token = _token;
7868 windowType = type;
7869 explicit = _explicit;
7870 }
7871
7872 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007873 pw.print(prefix); pw.print("token="); pw.println(token);
7874 pw.print(prefix); pw.print("windows="); pw.println(windows);
7875 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
7876 pw.print(" hidden="); pw.print(hidden);
7877 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007878 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
7879 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
7880 pw.print(" waitingToHide="); pw.print(waitingToHide);
7881 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
7882 pw.print(" sendingToTop="); pw.println(sendingToTop);
7883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007884 }
7885
7886 @Override
7887 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007888 if (stringName == null) {
7889 StringBuilder sb = new StringBuilder();
7890 sb.append("WindowToken{");
7891 sb.append(Integer.toHexString(System.identityHashCode(this)));
7892 sb.append(" token="); sb.append(token); sb.append('}');
7893 stringName = sb.toString();
7894 }
7895 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007896 }
7897 };
7898
7899 class AppWindowToken extends WindowToken {
7900 // Non-null only for application tokens.
7901 final IApplicationToken appToken;
7902
7903 // All of the windows and child windows that are included in this
7904 // application token. Note this list is NOT sorted!
7905 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
7906
7907 int groupId = -1;
7908 boolean appFullscreen;
7909 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07007910
7911 // The input dispatching timeout for this application token in nanoseconds.
7912 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07007913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007914 // These are used for determining when all windows associated with
7915 // an activity have been drawn, so they can be made visible together
7916 // at the same time.
7917 int lastTransactionSequence = mTransactionSequence-1;
7918 int numInterestingWindows;
7919 int numDrawnWindows;
7920 boolean inPendingTransaction;
7921 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07007922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 // Is this token going to be hidden in a little while? If so, it
7924 // won't be taken into account for setting the screen orientation.
7925 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 // Is this window's surface needed? This is almost like hidden, except
7928 // it will sometimes be true a little earlier: when the token has
7929 // been shown, but is still waiting for its app transition to execute
7930 // before making its windows shown.
7931 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07007932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 // Have we told the window clients to hide themselves?
7934 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 // Last visibility state we reported to the app token.
7937 boolean reportedVisible;
7938
7939 // Set to true when the token has been removed from the window mgr.
7940 boolean removed;
7941
7942 // Have we been asked to have this token keep the screen frozen?
7943 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07007944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945 boolean animating;
7946 Animation animation;
7947 boolean hasTransformation;
7948 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07007949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007950 // Offset to the window of all layers in the token, for use by
7951 // AppWindowToken animations.
7952 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07007953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007954 // Information about an application starting window if displayed.
7955 StartingData startingData;
7956 WindowState startingWindow;
7957 View startingView;
7958 boolean startingDisplayed;
7959 boolean startingMoved;
7960 boolean firstWindowDrawn;
7961
7962 AppWindowToken(IApplicationToken _token) {
7963 super(_token.asBinder(),
7964 WindowManager.LayoutParams.TYPE_APPLICATION, true);
7965 appWindowToken = this;
7966 appToken = _token;
7967 }
Romain Guy06882f82009-06-10 13:36:04 -07007968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007970 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007971 TAG, "Setting animation in " + this + ": " + anim);
7972 animation = anim;
7973 animating = false;
7974 anim.restrictDuration(MAX_ANIMATION_DURATION);
7975 anim.scaleCurrentDuration(mTransitionAnimationScale);
7976 int zorder = anim.getZAdjustment();
7977 int adj = 0;
7978 if (zorder == Animation.ZORDER_TOP) {
7979 adj = TYPE_LAYER_OFFSET;
7980 } else if (zorder == Animation.ZORDER_BOTTOM) {
7981 adj = -TYPE_LAYER_OFFSET;
7982 }
Romain Guy06882f82009-06-10 13:36:04 -07007983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 if (animLayerAdjustment != adj) {
7985 animLayerAdjustment = adj;
7986 updateLayers();
7987 }
7988 }
Romain Guy06882f82009-06-10 13:36:04 -07007989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007990 public void setDummyAnimation() {
7991 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007992 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007993 TAG, "Setting dummy animation in " + this);
7994 animation = sDummyAnimation;
7995 }
7996 }
7997
7998 public void clearAnimation() {
7999 if (animation != null) {
8000 animation = null;
8001 animating = true;
8002 }
8003 }
Romain Guy06882f82009-06-10 13:36:04 -07008004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005 void updateLayers() {
8006 final int N = allAppWindows.size();
8007 final int adj = animLayerAdjustment;
8008 for (int i=0; i<N; i++) {
8009 WindowState w = allAppWindows.get(i);
8010 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008011 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 + w.mAnimLayer);
8013 if (w == mInputMethodTarget) {
8014 setInputMethodAnimLayerAdjustment(adj);
8015 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008016 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008017 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008018 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 }
8020 }
Romain Guy06882f82009-06-10 13:36:04 -07008021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 void sendAppVisibilityToClients() {
8023 final int N = allAppWindows.size();
8024 for (int i=0; i<N; i++) {
8025 WindowState win = allAppWindows.get(i);
8026 if (win == startingWindow && clientHidden) {
8027 // Don't hide the starting window.
8028 continue;
8029 }
8030 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008031 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008032 "Setting visibility of " + win + ": " + (!clientHidden));
8033 win.mClient.dispatchAppVisibility(!clientHidden);
8034 } catch (RemoteException e) {
8035 }
8036 }
8037 }
Romain Guy06882f82009-06-10 13:36:04 -07008038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 void showAllWindowsLocked() {
8040 final int NW = allAppWindows.size();
8041 for (int i=0; i<NW; i++) {
8042 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008043 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 "performing show on: " + w);
8045 w.performShowLocked();
8046 }
8047 }
Romain Guy06882f82009-06-10 13:36:04 -07008048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008049 // This must be called while inside a transaction.
8050 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008051 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008052 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008054 if (animation == sDummyAnimation) {
8055 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008056 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 // when it is really time to animate, this will be set to
8058 // a real animation and the next call will execute normally.
8059 return false;
8060 }
Romain Guy06882f82009-06-10 13:36:04 -07008061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008062 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8063 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008064 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008065 TAG, "Starting animation in " + this +
8066 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8067 + " scale=" + mTransitionAnimationScale
8068 + " allDrawn=" + allDrawn + " animating=" + animating);
8069 animation.initialize(dw, dh, dw, dh);
8070 animation.setStartTime(currentTime);
8071 animating = true;
8072 }
8073 transformation.clear();
8074 final boolean more = animation.getTransformation(
8075 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008076 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077 TAG, "Stepped animation in " + this +
8078 ": more=" + more + ", xform=" + transformation);
8079 if (more) {
8080 // we're done!
8081 hasTransformation = true;
8082 return true;
8083 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008084 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008085 TAG, "Finished animation in " + this +
8086 " @ " + currentTime);
8087 animation = null;
8088 }
8089 } else if (animation != null) {
8090 // If the display is frozen, and there is a pending animation,
8091 // clear it and make sure we run the cleanup code.
8092 animating = true;
8093 animation = null;
8094 }
8095
8096 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 if (!animating) {
8099 return false;
8100 }
8101
8102 clearAnimation();
8103 animating = false;
8104 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8105 moveInputMethodWindowsIfNeededLocked(true);
8106 }
Romain Guy06882f82009-06-10 13:36:04 -07008107
Joe Onorato8a9b2202010-02-26 18:56:32 -08008108 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008109 TAG, "Animation done in " + this
8110 + ": reportedVisible=" + reportedVisible);
8111
8112 transformation.clear();
8113 if (animLayerAdjustment != 0) {
8114 animLayerAdjustment = 0;
8115 updateLayers();
8116 }
Romain Guy06882f82009-06-10 13:36:04 -07008117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008118 final int N = windows.size();
8119 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008120 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121 }
8122 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008124 return false;
8125 }
8126
8127 void updateReportedVisibilityLocked() {
8128 if (appToken == null) {
8129 return;
8130 }
Romain Guy06882f82009-06-10 13:36:04 -07008131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 int numInteresting = 0;
8133 int numVisible = 0;
8134 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008135
Joe Onorato8a9b2202010-02-26 18:56:32 -08008136 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 final int N = allAppWindows.size();
8138 for (int i=0; i<N; i++) {
8139 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008140 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008141 || win.mViewVisibility != View.VISIBLE
8142 || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143 continue;
8144 }
8145 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008146 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008147 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008149 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008150 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008151 + " pv=" + win.mPolicyVisibility
8152 + " dp=" + win.mDrawPending
8153 + " cdp=" + win.mCommitDrawPending
8154 + " ah=" + win.mAttachedHidden
8155 + " th="
8156 + (win.mAppToken != null
8157 ? win.mAppToken.hiddenRequested : false)
8158 + " a=" + win.mAnimating);
8159 }
8160 }
8161 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008162 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 if (!win.isAnimating()) {
8164 numVisible++;
8165 }
8166 nowGone = false;
8167 } else if (win.isAnimating()) {
8168 nowGone = false;
8169 }
8170 }
Romain Guy06882f82009-06-10 13:36:04 -07008171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008172 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008173 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 + numInteresting + " visible=" + numVisible);
8175 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008176 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177 TAG, "Visibility changed in " + this
8178 + ": vis=" + nowVisible);
8179 reportedVisible = nowVisible;
8180 Message m = mH.obtainMessage(
8181 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8182 nowVisible ? 1 : 0,
8183 nowGone ? 1 : 0,
8184 this);
8185 mH.sendMessage(m);
8186 }
8187 }
Romain Guy06882f82009-06-10 13:36:04 -07008188
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008189 WindowState findMainWindow() {
8190 int j = windows.size();
8191 while (j > 0) {
8192 j--;
8193 WindowState win = windows.get(j);
8194 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8195 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8196 return win;
8197 }
8198 }
8199 return null;
8200 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008202 void dump(PrintWriter pw, String prefix) {
8203 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008204 if (appToken != null) {
8205 pw.print(prefix); pw.println("app=true");
8206 }
8207 if (allAppWindows.size() > 0) {
8208 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8209 }
8210 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008211 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008212 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8213 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8214 pw.print(" clientHidden="); pw.print(clientHidden);
8215 pw.print(" willBeHidden="); pw.print(willBeHidden);
8216 pw.print(" reportedVisible="); pw.println(reportedVisible);
8217 if (paused || freezingScreen) {
8218 pw.print(prefix); pw.print("paused="); pw.print(paused);
8219 pw.print(" freezingScreen="); pw.println(freezingScreen);
8220 }
8221 if (numInterestingWindows != 0 || numDrawnWindows != 0
8222 || inPendingTransaction || allDrawn) {
8223 pw.print(prefix); pw.print("numInterestingWindows=");
8224 pw.print(numInterestingWindows);
8225 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8226 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8227 pw.print(" allDrawn="); pw.println(allDrawn);
8228 }
8229 if (animating || animation != null) {
8230 pw.print(prefix); pw.print("animating="); pw.print(animating);
8231 pw.print(" animation="); pw.println(animation);
8232 }
8233 if (animLayerAdjustment != 0) {
8234 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8235 }
8236 if (hasTransformation) {
8237 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8238 pw.print(" transformation="); transformation.printShortString(pw);
8239 pw.println();
8240 }
8241 if (startingData != null || removed || firstWindowDrawn) {
8242 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8243 pw.print(" removed="); pw.print(removed);
8244 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8245 }
8246 if (startingWindow != null || startingView != null
8247 || startingDisplayed || startingMoved) {
8248 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8249 pw.print(" startingView="); pw.print(startingView);
8250 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8251 pw.print(" startingMoved"); pw.println(startingMoved);
8252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008253 }
8254
8255 @Override
8256 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008257 if (stringName == null) {
8258 StringBuilder sb = new StringBuilder();
8259 sb.append("AppWindowToken{");
8260 sb.append(Integer.toHexString(System.identityHashCode(this)));
8261 sb.append(" token="); sb.append(token); sb.append('}');
8262 stringName = sb.toString();
8263 }
8264 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 }
8266 }
Romain Guy06882f82009-06-10 13:36:04 -07008267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008268 // -------------------------------------------------------------
8269 // DummyAnimation
8270 // -------------------------------------------------------------
8271
8272 // This is an animation that does nothing: it just immediately finishes
8273 // itself every time it is called. It is used as a stub animation in cases
8274 // where we want to synchronize multiple things that may be animating.
8275 static final class DummyAnimation extends Animation {
8276 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8277 return false;
8278 }
8279 }
8280 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008282 // -------------------------------------------------------------
8283 // Async Handler
8284 // -------------------------------------------------------------
8285
8286 static final class StartingData {
8287 final String pkg;
8288 final int theme;
8289 final CharSequence nonLocalizedLabel;
8290 final int labelRes;
8291 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07008292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008293 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
8294 int _labelRes, int _icon) {
8295 pkg = _pkg;
8296 theme = _theme;
8297 nonLocalizedLabel = _nonLocalizedLabel;
8298 labelRes = _labelRes;
8299 icon = _icon;
8300 }
8301 }
8302
8303 private final class H extends Handler {
8304 public static final int REPORT_FOCUS_CHANGE = 2;
8305 public static final int REPORT_LOSING_FOCUS = 3;
8306 public static final int ANIMATE = 4;
8307 public static final int ADD_STARTING = 5;
8308 public static final int REMOVE_STARTING = 6;
8309 public static final int FINISHED_STARTING = 7;
8310 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008311 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8312 public static final int HOLD_SCREEN_CHANGED = 12;
8313 public static final int APP_TRANSITION_TIMEOUT = 13;
8314 public static final int PERSIST_ANIMATION_SCALE = 14;
8315 public static final int FORCE_GC = 15;
8316 public static final int ENABLE_SCREEN = 16;
8317 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008318 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008319 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008320 public static final int DRAG_START_TIMEOUT = 20;
Romain Guy06882f82009-06-10 13:36:04 -07008321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008324 public H() {
8325 }
Romain Guy06882f82009-06-10 13:36:04 -07008326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008327 @Override
8328 public void handleMessage(Message msg) {
8329 switch (msg.what) {
8330 case REPORT_FOCUS_CHANGE: {
8331 WindowState lastFocus;
8332 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 synchronized(mWindowMap) {
8335 lastFocus = mLastFocus;
8336 newFocus = mCurrentFocus;
8337 if (lastFocus == newFocus) {
8338 // Focus is not changing, so nothing to do.
8339 return;
8340 }
8341 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008342 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008343 // + " to " + newFocus);
8344 if (newFocus != null && lastFocus != null
8345 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008346 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008347 mLosingFocus.add(lastFocus);
8348 lastFocus = null;
8349 }
8350 }
8351
8352 if (lastFocus != newFocus) {
8353 //System.out.println("Changing focus from " + lastFocus
8354 // + " to " + newFocus);
8355 if (newFocus != null) {
8356 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008357 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008358 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8359 } catch (RemoteException e) {
8360 // Ignore if process has died.
8361 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008362 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008363 }
8364
8365 if (lastFocus != null) {
8366 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008367 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008368 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8369 } catch (RemoteException e) {
8370 // Ignore if process has died.
8371 }
8372 }
8373 }
8374 } break;
8375
8376 case REPORT_LOSING_FOCUS: {
8377 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008379 synchronized(mWindowMap) {
8380 losers = mLosingFocus;
8381 mLosingFocus = new ArrayList<WindowState>();
8382 }
8383
8384 final int N = losers.size();
8385 for (int i=0; i<N; i++) {
8386 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008387 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8389 } catch (RemoteException e) {
8390 // Ignore if process has died.
8391 }
8392 }
8393 } break;
8394
8395 case ANIMATE: {
8396 synchronized(mWindowMap) {
8397 mAnimationPending = false;
8398 performLayoutAndPlaceSurfacesLocked();
8399 }
8400 } break;
8401
8402 case ADD_STARTING: {
8403 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8404 final StartingData sd = wtoken.startingData;
8405
8406 if (sd == null) {
8407 // Animation has been canceled... do nothing.
8408 return;
8409 }
Romain Guy06882f82009-06-10 13:36:04 -07008410
Joe Onorato8a9b2202010-02-26 18:56:32 -08008411 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008414 View view = null;
8415 try {
8416 view = mPolicy.addStartingWindow(
8417 wtoken.token, sd.pkg,
8418 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
8419 sd.icon);
8420 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008421 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008422 }
8423
8424 if (view != null) {
8425 boolean abort = false;
8426
8427 synchronized(mWindowMap) {
8428 if (wtoken.removed || wtoken.startingData == null) {
8429 // If the window was successfully added, then
8430 // we need to remove it.
8431 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008432 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 "Aborted starting " + wtoken
8434 + ": removed=" + wtoken.removed
8435 + " startingData=" + wtoken.startingData);
8436 wtoken.startingWindow = null;
8437 wtoken.startingData = null;
8438 abort = true;
8439 }
8440 } else {
8441 wtoken.startingView = view;
8442 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008443 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008444 "Added starting " + wtoken
8445 + ": startingWindow="
8446 + wtoken.startingWindow + " startingView="
8447 + wtoken.startingView);
8448 }
8449
8450 if (abort) {
8451 try {
8452 mPolicy.removeStartingWindow(wtoken.token, view);
8453 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008454 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 }
8456 }
8457 }
8458 } break;
8459
8460 case REMOVE_STARTING: {
8461 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8462 IBinder token = null;
8463 View view = null;
8464 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008465 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 + wtoken + ": startingWindow="
8467 + wtoken.startingWindow + " startingView="
8468 + wtoken.startingView);
8469 if (wtoken.startingWindow != null) {
8470 view = wtoken.startingView;
8471 token = wtoken.token;
8472 wtoken.startingData = null;
8473 wtoken.startingView = null;
8474 wtoken.startingWindow = null;
8475 }
8476 }
8477 if (view != null) {
8478 try {
8479 mPolicy.removeStartingWindow(token, view);
8480 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008481 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 }
8483 }
8484 } break;
8485
8486 case FINISHED_STARTING: {
8487 IBinder token = null;
8488 View view = null;
8489 while (true) {
8490 synchronized (mWindowMap) {
8491 final int N = mFinishedStarting.size();
8492 if (N <= 0) {
8493 break;
8494 }
8495 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8496
Joe Onorato8a9b2202010-02-26 18:56:32 -08008497 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008498 "Finished starting " + wtoken
8499 + ": startingWindow=" + wtoken.startingWindow
8500 + " startingView=" + wtoken.startingView);
8501
8502 if (wtoken.startingWindow == null) {
8503 continue;
8504 }
8505
8506 view = wtoken.startingView;
8507 token = wtoken.token;
8508 wtoken.startingData = null;
8509 wtoken.startingView = null;
8510 wtoken.startingWindow = null;
8511 }
8512
8513 try {
8514 mPolicy.removeStartingWindow(token, view);
8515 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008516 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 }
8518 }
8519 } break;
8520
8521 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8522 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8523
8524 boolean nowVisible = msg.arg1 != 0;
8525 boolean nowGone = msg.arg2 != 0;
8526
8527 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008528 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008529 TAG, "Reporting visible in " + wtoken
8530 + " visible=" + nowVisible
8531 + " gone=" + nowGone);
8532 if (nowVisible) {
8533 wtoken.appToken.windowsVisible();
8534 } else {
8535 wtoken.appToken.windowsGone();
8536 }
8537 } catch (RemoteException ex) {
8538 }
8539 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 case WINDOW_FREEZE_TIMEOUT: {
8542 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008543 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008544 int i = mWindows.size();
8545 while (i > 0) {
8546 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008547 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 if (w.mOrientationChanging) {
8549 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008550 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008551 }
8552 }
8553 performLayoutAndPlaceSurfacesLocked();
8554 }
8555 break;
8556 }
Romain Guy06882f82009-06-10 13:36:04 -07008557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008558 case HOLD_SCREEN_CHANGED: {
8559 Session oldHold;
8560 Session newHold;
8561 synchronized (mWindowMap) {
8562 oldHold = mLastReportedHold;
8563 newHold = (Session)msg.obj;
8564 mLastReportedHold = newHold;
8565 }
Romain Guy06882f82009-06-10 13:36:04 -07008566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008567 if (oldHold != newHold) {
8568 try {
8569 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008570 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008571 "window",
8572 BatteryStats.WAKE_TYPE_WINDOW);
8573 }
8574 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008575 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 "window",
8577 BatteryStats.WAKE_TYPE_WINDOW);
8578 }
8579 } catch (RemoteException e) {
8580 }
8581 }
8582 break;
8583 }
Romain Guy06882f82009-06-10 13:36:04 -07008584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 case APP_TRANSITION_TIMEOUT: {
8586 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008587 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008588 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 "*** APP TRANSITION TIMEOUT");
8590 mAppTransitionReady = true;
8591 mAppTransitionTimeout = true;
8592 performLayoutAndPlaceSurfacesLocked();
8593 }
8594 }
8595 break;
8596 }
Romain Guy06882f82009-06-10 13:36:04 -07008597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598 case PERSIST_ANIMATION_SCALE: {
8599 Settings.System.putFloat(mContext.getContentResolver(),
8600 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8601 Settings.System.putFloat(mContext.getContentResolver(),
8602 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8603 break;
8604 }
Romain Guy06882f82009-06-10 13:36:04 -07008605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 case FORCE_GC: {
8607 synchronized(mWindowMap) {
8608 if (mAnimationPending) {
8609 // If we are animating, don't do the gc now but
8610 // delay a bit so we don't interrupt the animation.
8611 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8612 2000);
8613 return;
8614 }
8615 // If we are currently rotating the display, it will
8616 // schedule a new message when done.
8617 if (mDisplayFrozen) {
8618 return;
8619 }
8620 mFreezeGcPending = 0;
8621 }
8622 Runtime.getRuntime().gc();
8623 break;
8624 }
Romain Guy06882f82009-06-10 13:36:04 -07008625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 case ENABLE_SCREEN: {
8627 performEnableScreen();
8628 break;
8629 }
Romain Guy06882f82009-06-10 13:36:04 -07008630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008631 case APP_FREEZE_TIMEOUT: {
8632 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008633 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008634 int i = mAppTokens.size();
8635 while (i > 0) {
8636 i--;
8637 AppWindowToken tok = mAppTokens.get(i);
8638 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008639 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008640 unsetAppFreezingScreenLocked(tok, true, true);
8641 }
8642 }
8643 }
8644 break;
8645 }
Romain Guy06882f82009-06-10 13:36:04 -07008646
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008647 case SEND_NEW_CONFIGURATION: {
8648 removeMessages(SEND_NEW_CONFIGURATION);
8649 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008650 break;
8651 }
Romain Guy06882f82009-06-10 13:36:04 -07008652
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008653 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008654 if (mWindowsChanged) {
8655 synchronized (mWindowMap) {
8656 mWindowsChanged = false;
8657 }
8658 notifyWindowsChanged();
8659 }
8660 break;
8661 }
8662
Christopher Tatea53146c2010-09-07 11:57:52 -07008663 case DRAG_START_TIMEOUT: {
8664 IBinder win = (IBinder)msg.obj;
8665 if (DEBUG_DRAG) {
8666 Slog.w(TAG, "Timeout starting drag by win " + win);
8667 }
8668 synchronized (mWindowMap) {
8669 // !!! TODO: ANR the app that has failed to start the drag in time
8670 if (mDragState != null) {
8671 mDragState.reset();
8672 mDragState = null;
8673 }
8674 }
8675 }
8676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008677 }
8678 }
8679 }
8680
8681 // -------------------------------------------------------------
8682 // IWindowManager API
8683 // -------------------------------------------------------------
8684
8685 public IWindowSession openSession(IInputMethodClient client,
8686 IInputContext inputContext) {
8687 if (client == null) throw new IllegalArgumentException("null client");
8688 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008689 Session session = new Session(client, inputContext);
8690 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 }
8692
8693 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8694 synchronized (mWindowMap) {
8695 // The focus for the client is the window immediately below
8696 // where we would place the input method window.
8697 int idx = findDesiredInputMethodWindowIndexLocked(false);
8698 WindowState imFocus;
8699 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008700 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008701 if (imFocus != null) {
8702 if (imFocus.mSession.mClient != null &&
8703 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8704 return true;
8705 }
8706 }
8707 }
8708 }
8709 return false;
8710 }
Romain Guy06882f82009-06-10 13:36:04 -07008711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008712 // -------------------------------------------------------------
8713 // Internals
8714 // -------------------------------------------------------------
8715
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008716 final WindowState windowForClientLocked(Session session, IWindow client,
8717 boolean throwOnError) {
8718 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008719 }
Romain Guy06882f82009-06-10 13:36:04 -07008720
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008721 final WindowState windowForClientLocked(Session session, IBinder client,
8722 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008723 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008724 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008725 TAG, "Looking up client " + client + ": " + win);
8726 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008727 RuntimeException ex = new IllegalArgumentException(
8728 "Requested window " + client + " does not exist");
8729 if (throwOnError) {
8730 throw ex;
8731 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008732 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 return null;
8734 }
8735 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008736 RuntimeException ex = new IllegalArgumentException(
8737 "Requested window " + client + " is in session " +
8738 win.mSession + ", not " + session);
8739 if (throwOnError) {
8740 throw ex;
8741 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008742 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008743 return null;
8744 }
8745
8746 return win;
8747 }
8748
Dianne Hackborna8f60182009-09-01 19:01:50 -07008749 final void rebuildAppWindowListLocked() {
8750 int NW = mWindows.size();
8751 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008752 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008753 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008754
Dianne Hackborna8f60182009-09-01 19:01:50 -07008755 // First remove all existing app windows.
8756 i=0;
8757 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07008758 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008759 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07008760 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008761 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008762 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008763 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008764 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008765 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008766 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008767 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8768 && lastWallpaper == i-1) {
8769 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008770 }
8771 i++;
8772 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008773
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008774 // The wallpaper window(s) typically live at the bottom of the stack,
8775 // so skip them before adding app tokens.
8776 lastWallpaper++;
8777 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008778
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008779 // First add all of the exiting app tokens... these are no longer
8780 // in the main app list, but still have windows shown. We put them
8781 // in the back because now that the animation is over we no longer
8782 // will care about them.
8783 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008784 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008785 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8786 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008787
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008788 // And add in the still active app tokens in Z order.
8789 NT = mAppTokens.size();
8790 for (int j=0; j<NT; j++) {
8791 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008792 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008793
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008794 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008795 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008796 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008797 + " windows but added " + i);
8798 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008799 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008801 private final void assignLayersLocked() {
8802 int N = mWindows.size();
8803 int curBaseLayer = 0;
8804 int curLayer = 0;
8805 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008807 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008808 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008809 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8810 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008811 curLayer += WINDOW_LAYER_MULTIPLIER;
8812 w.mLayer = curLayer;
8813 } else {
8814 curBaseLayer = curLayer = w.mBaseLayer;
8815 w.mLayer = curLayer;
8816 }
8817 if (w.mTargetAppToken != null) {
8818 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
8819 } else if (w.mAppToken != null) {
8820 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
8821 } else {
8822 w.mAnimLayer = w.mLayer;
8823 }
8824 if (w.mIsImWindow) {
8825 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008826 } else if (w.mIsWallpaper) {
8827 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008829 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008830 + w.mAnimLayer);
8831 //System.out.println(
8832 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8833 }
8834 }
8835
8836 private boolean mInLayout = false;
8837 private final void performLayoutAndPlaceSurfacesLocked() {
8838 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008839 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008840 throw new RuntimeException("Recursive call!");
8841 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008842 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 return;
8844 }
8845
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008846 if (mWaitingForConfig) {
8847 // Our configuration has changed (most likely rotation), but we
8848 // don't yet have the complete configuration to report to
8849 // applications. Don't do any window layout until we have it.
8850 return;
8851 }
8852
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008853 if (mDisplay == null) {
8854 // Not yet initialized, nothing to do.
8855 return;
8856 }
8857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008858 boolean recoveringMemory = false;
8859 if (mForceRemoves != null) {
8860 recoveringMemory = true;
8861 // Wait a little it for things to settle down, and off we go.
8862 for (int i=0; i<mForceRemoves.size(); i++) {
8863 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008864 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008865 removeWindowInnerLocked(ws.mSession, ws);
8866 }
8867 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008868 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008869 Object tmp = new Object();
8870 synchronized (tmp) {
8871 try {
8872 tmp.wait(250);
8873 } catch (InterruptedException e) {
8874 }
8875 }
8876 }
Romain Guy06882f82009-06-10 13:36:04 -07008877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008878 mInLayout = true;
8879 try {
8880 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07008881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 int i = mPendingRemove.size()-1;
8883 if (i >= 0) {
8884 while (i >= 0) {
8885 WindowState w = mPendingRemove.get(i);
8886 removeWindowInnerLocked(w.mSession, w);
8887 i--;
8888 }
8889 mPendingRemove.clear();
8890
8891 mInLayout = false;
8892 assignLayersLocked();
8893 mLayoutNeeded = true;
8894 performLayoutAndPlaceSurfacesLocked();
8895
8896 } else {
8897 mInLayout = false;
8898 if (mLayoutNeeded) {
8899 requestAnimationLocked(0);
8900 }
8901 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008902 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008903 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8904 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008906 } catch (RuntimeException e) {
8907 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008908 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008909 }
8910 }
8911
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008912 private final int performLayoutLockedInner() {
8913 if (!mLayoutNeeded) {
8914 return 0;
8915 }
8916
8917 mLayoutNeeded = false;
8918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008919 final int dw = mDisplay.getWidth();
8920 final int dh = mDisplay.getHeight();
8921
8922 final int N = mWindows.size();
8923 int i;
8924
Joe Onorato8a9b2202010-02-26 18:56:32 -08008925 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008926 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
8927
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008928 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07008929
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008930 int seq = mLayoutSeq+1;
8931 if (seq < 0) seq = 0;
8932 mLayoutSeq = seq;
8933
8934 // First perform layout of any root windows (not attached
8935 // to another window).
8936 int topAttached = -1;
8937 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008938 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008939
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008940 // Don't do layout of a window if it is not visible, or
8941 // soon won't be visible, to avoid wasting time and funky
8942 // changes while a window is animating away.
8943 final AppWindowToken atoken = win.mAppToken;
8944 final boolean gone = win.mViewVisibility == View.GONE
8945 || !win.mRelayoutCalled
8946 || win.mRootToken.hidden
8947 || (atoken != null && atoken.hiddenRequested)
8948 || win.mAttachedHidden
8949 || win.mExiting || win.mDestroying;
8950
8951 if (!win.mLayoutAttached) {
8952 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
8953 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8954 + " mLayoutAttached=" + win.mLayoutAttached);
8955 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
8956 + win.mViewVisibility + " mRelayoutCalled="
8957 + win.mRelayoutCalled + " hidden="
8958 + win.mRootToken.hidden + " hiddenRequested="
8959 + (atoken != null && atoken.hiddenRequested)
8960 + " mAttachedHidden=" + win.mAttachedHidden);
8961 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008962
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008963 // If this view is GONE, then skip it -- keep the current
8964 // frame, and let the caller know so they can ignore it
8965 // if they want. (We do the normal layout for INVISIBLE
8966 // windows, since that means "perform layout as normal,
8967 // just don't display").
8968 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008969 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008970 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8971 win.mLayoutSeq = seq;
8972 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8973 + win.mFrame + " mContainingFrame="
8974 + win.mContainingFrame + " mDisplayFrame="
8975 + win.mDisplayFrame);
8976 } else {
8977 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008978 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008980 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008981
8982 // Now perform layout of attached windows, which usually
8983 // depend on the position of the window they are attached to.
8984 // XXX does not deal with windows that are attached to windows
8985 // that are themselves attached.
8986 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008987 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008988
8989 // If this view is GONE, then skip it -- keep the current
8990 // frame, and let the caller know so they can ignore it
8991 // if they want. (We do the normal layout for INVISIBLE
8992 // windows, since that means "perform layout as normal,
8993 // just don't display").
8994 if (win.mLayoutAttached) {
8995 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
8996 + " mHaveFrame=" + win.mHaveFrame
8997 + " mViewVisibility=" + win.mViewVisibility
8998 + " mRelayoutCalled=" + win.mRelayoutCalled);
8999 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9000 || !win.mHaveFrame) {
9001 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9002 win.mLayoutSeq = seq;
9003 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9004 + win.mFrame + " mContainingFrame="
9005 + win.mContainingFrame + " mDisplayFrame="
9006 + win.mDisplayFrame);
9007 }
9008 }
9009 }
Jeff Brown349703e2010-06-22 01:27:15 -07009010
9011 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009012 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009013
9014 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 }
Romain Guy06882f82009-06-10 13:36:04 -07009016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009017 private final void performLayoutAndPlaceSurfacesLockedInner(
9018 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009019 if (mDisplay == null) {
9020 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9021 return;
9022 }
9023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 final long currentTime = SystemClock.uptimeMillis();
9025 final int dw = mDisplay.getWidth();
9026 final int dh = mDisplay.getHeight();
9027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 int i;
9029
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009030 if (mFocusMayChange) {
9031 mFocusMayChange = false;
9032 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9033 }
9034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 // Initialize state of exiting tokens.
9036 for (i=mExitingTokens.size()-1; i>=0; i--) {
9037 mExitingTokens.get(i).hasVisible = false;
9038 }
9039
9040 // Initialize state of exiting applications.
9041 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9042 mExitingAppTokens.get(i).hasVisible = false;
9043 }
9044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009045 boolean orientationChangeComplete = true;
9046 Session holdScreen = null;
9047 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009048 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 boolean focusDisplayed = false;
9050 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009051 boolean createWatermark = false;
9052
9053 if (mFxSession == null) {
9054 mFxSession = new SurfaceSession();
9055 createWatermark = true;
9056 }
9057
9058 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059
9060 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009061
9062 if (createWatermark) {
9063 createWatermark();
9064 }
9065 if (mWatermark != null) {
9066 mWatermark.positionSurface(dw, dh);
9067 }
9068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009070 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009071 int repeats = 0;
9072 int changes = 0;
9073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009075 repeats++;
9076 if (repeats > 6) {
9077 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9078 mLayoutNeeded = false;
9079 break;
9080 }
9081
9082 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9083 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9084 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9085 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9086 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9087 assignLayersLocked();
9088 mLayoutNeeded = true;
9089 }
9090 }
9091 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9092 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9093 if (updateOrientationFromAppTokensLocked()) {
9094 mLayoutNeeded = true;
9095 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9096 }
9097 }
9098 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9099 mLayoutNeeded = true;
9100 }
9101 }
9102
9103 // FIRST LOOP: Perform a layout, if needed.
9104 if (repeats < 4) {
9105 changes = performLayoutLockedInner();
9106 if (changes != 0) {
9107 continue;
9108 }
9109 } else {
9110 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9111 changes = 0;
9112 }
9113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 final int transactionSequence = ++mTransactionSequence;
9115
9116 // Update animations of all applications, including those
9117 // associated with exiting/removed apps
9118 boolean tokensAnimating = false;
9119 final int NAT = mAppTokens.size();
9120 for (i=0; i<NAT; i++) {
9121 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9122 tokensAnimating = true;
9123 }
9124 }
9125 final int NEAT = mExitingAppTokens.size();
9126 for (i=0; i<NEAT; i++) {
9127 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9128 tokensAnimating = true;
9129 }
9130 }
9131
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009132 // SECOND LOOP: Execute animations and update visibility of windows.
9133
Joe Onorato8a9b2202010-02-26 18:56:32 -08009134 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009135 + transactionSequence + " tokensAnimating="
9136 + tokensAnimating);
9137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009138 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139
9140 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009141 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009142 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009143
9144 mPolicy.beginAnimationLw(dw, dh);
9145
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009146 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009149 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009150
9151 final WindowManager.LayoutParams attrs = w.mAttrs;
9152
9153 if (w.mSurface != null) {
9154 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009155 if (w.commitFinishDrawingLocked(currentTime)) {
9156 if ((w.mAttrs.flags
9157 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009158 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009159 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009160 wallpaperMayChange = true;
9161 }
9162 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009163
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009164 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 if (w.stepAnimationLocked(currentTime, dw, dh)) {
9166 animating = true;
9167 //w.dump(" ");
9168 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009169 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9170 wallpaperMayChange = true;
9171 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009172
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009173 if (mPolicy.doesForceHide(w, attrs)) {
9174 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009175 if (DEBUG_VISIBILITY) Slog.v(TAG,
9176 "Animation done that could impact force hide: "
9177 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009178 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009179 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009180 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9181 forceHiding = true;
9182 }
9183 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9184 boolean changed;
9185 if (forceHiding) {
9186 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009187 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9188 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009189 } else {
9190 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009191 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9192 "Now policy shown: " + w);
9193 if (changed) {
9194 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009195 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009196 // Assume we will need to animate. If
9197 // we don't (because the wallpaper will
9198 // stay with the lock screen), then we will
9199 // clean up later.
9200 Animation a = mPolicy.createForceHideEnterAnimation();
9201 if (a != null) {
9202 w.setAnimation(a);
9203 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009204 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009205 if (mCurrentFocus == null ||
9206 mCurrentFocus.mLayer < w.mLayer) {
9207 // We are showing on to of the current
9208 // focus, so re-evaluate focus to make
9209 // sure it is correct.
9210 mFocusMayChange = true;
9211 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009212 }
9213 }
9214 if (changed && (attrs.flags
9215 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9216 wallpaperMayChange = true;
9217 }
9218 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009220 mPolicy.animatingWindowLw(w, attrs);
9221 }
9222
9223 final AppWindowToken atoken = w.mAppToken;
9224 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9225 if (atoken.lastTransactionSequence != transactionSequence) {
9226 atoken.lastTransactionSequence = transactionSequence;
9227 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9228 atoken.startingDisplayed = false;
9229 }
9230 if ((w.isOnScreen() || w.mAttrs.type
9231 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9232 && !w.mExiting && !w.mDestroying) {
9233 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009234 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009235 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009237 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009238 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009239 + " pv=" + w.mPolicyVisibility
9240 + " dp=" + w.mDrawPending
9241 + " cdp=" + w.mCommitDrawPending
9242 + " ah=" + w.mAttachedHidden
9243 + " th=" + atoken.hiddenRequested
9244 + " a=" + w.mAnimating);
9245 }
9246 }
9247 if (w != atoken.startingWindow) {
9248 if (!atoken.freezingScreen || !w.mAppFreezing) {
9249 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009250 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009252 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 "tokenMayBeDrawn: " + atoken
9254 + " freezingScreen=" + atoken.freezingScreen
9255 + " mAppFreezing=" + w.mAppFreezing);
9256 tokenMayBeDrawn = true;
9257 }
9258 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009259 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009260 atoken.startingDisplayed = true;
9261 }
9262 }
9263 } else if (w.mReadyToShow) {
9264 w.performShowLocked();
9265 }
9266 }
9267
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009268 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009269
9270 if (tokenMayBeDrawn) {
9271 // See if any windows have been drawn, so they (and others
9272 // associated with them) can now be shown.
9273 final int NT = mTokenList.size();
9274 for (i=0; i<NT; i++) {
9275 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9276 if (wtoken == null) {
9277 continue;
9278 }
9279 if (wtoken.freezingScreen) {
9280 int numInteresting = wtoken.numInterestingWindows;
9281 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009282 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283 "allDrawn: " + wtoken
9284 + " interesting=" + numInteresting
9285 + " drawn=" + wtoken.numDrawnWindows);
9286 wtoken.showAllWindowsLocked();
9287 unsetAppFreezingScreenLocked(wtoken, false, true);
9288 orientationChangeComplete = true;
9289 }
9290 } else if (!wtoken.allDrawn) {
9291 int numInteresting = wtoken.numInterestingWindows;
9292 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009293 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 "allDrawn: " + wtoken
9295 + " interesting=" + numInteresting
9296 + " drawn=" + wtoken.numDrawnWindows);
9297 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009298 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299
9300 // We can now show all of the drawn windows!
9301 if (!mOpeningApps.contains(wtoken)) {
9302 wtoken.showAllWindowsLocked();
9303 }
9304 }
9305 }
9306 }
9307 }
9308
9309 // If we are ready to perform an app transition, check through
9310 // all of the app tokens to be shown and see if they are ready
9311 // to go.
9312 if (mAppTransitionReady) {
9313 int NN = mOpeningApps.size();
9314 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009315 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009316 "Checking " + NN + " opening apps (frozen="
9317 + mDisplayFrozen + " timeout="
9318 + mAppTransitionTimeout + ")...");
9319 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9320 // If the display isn't frozen, wait to do anything until
9321 // all of the apps are ready. Otherwise just go because
9322 // we'll unfreeze the display when everyone is ready.
9323 for (i=0; i<NN && goodToGo; i++) {
9324 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009325 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009326 "Check opening app" + wtoken + ": allDrawn="
9327 + wtoken.allDrawn + " startingDisplayed="
9328 + wtoken.startingDisplayed);
9329 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9330 && !wtoken.startingMoved) {
9331 goodToGo = false;
9332 }
9333 }
9334 }
9335 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009336 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009337 int transit = mNextAppTransition;
9338 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009339 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009341 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009342 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009343 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009344 mAppTransitionTimeout = false;
9345 mStartingIconInTransition = false;
9346 mSkipAppTransitionAnimation = false;
9347
9348 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9349
Dianne Hackborna8f60182009-09-01 19:01:50 -07009350 // If there are applications waiting to come to the
9351 // top of the stack, now is the time to move their windows.
9352 // (Note that we don't do apps going to the bottom
9353 // here -- we want to keep their windows in the old
9354 // Z-order until the animation completes.)
9355 if (mToTopApps.size() > 0) {
9356 NN = mAppTokens.size();
9357 for (i=0; i<NN; i++) {
9358 AppWindowToken wtoken = mAppTokens.get(i);
9359 if (wtoken.sendingToTop) {
9360 wtoken.sendingToTop = false;
9361 moveAppWindowsLocked(wtoken, NN, false);
9362 }
9363 }
9364 mToTopApps.clear();
9365 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009366
Dianne Hackborn25994b42009-09-04 14:21:19 -07009367 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009368
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009369 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009370 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009371
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009372 // The top-most window will supply the layout params,
9373 // and we will determine it below.
9374 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009375 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009376 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009377
Joe Onorato8a9b2202010-02-26 18:56:32 -08009378 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009379 "New wallpaper target=" + mWallpaperTarget
9380 + ", lower target=" + mLowerWallpaperTarget
9381 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009382 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009383 // Do a first pass through the tokens for two
9384 // things:
9385 // (1) Determine if both the closing and opening
9386 // app token sets are wallpaper targets, in which
9387 // case special animations are needed
9388 // (since the wallpaper needs to stay static
9389 // behind them).
9390 // (2) Find the layout params of the top-most
9391 // application window in the tokens, which is
9392 // what will control the animation theme.
9393 final int NC = mClosingApps.size();
9394 NN = NC + mOpeningApps.size();
9395 for (i=0; i<NN; i++) {
9396 AppWindowToken wtoken;
9397 int mode;
9398 if (i < NC) {
9399 wtoken = mClosingApps.get(i);
9400 mode = 1;
9401 } else {
9402 wtoken = mOpeningApps.get(i-NC);
9403 mode = 2;
9404 }
9405 if (mLowerWallpaperTarget != null) {
9406 if (mLowerWallpaperTarget.mAppToken == wtoken
9407 || mUpperWallpaperTarget.mAppToken == wtoken) {
9408 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009409 }
9410 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009411 if (wtoken.appFullscreen) {
9412 WindowState ws = wtoken.findMainWindow();
9413 if (ws != null) {
9414 // If this is a compatibility mode
9415 // window, we will always use its anim.
9416 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9417 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009418 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009419 bestAnimLayer = Integer.MAX_VALUE;
9420 } else if (ws.mLayer > bestAnimLayer) {
9421 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009422 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009423 bestAnimLayer = ws.mLayer;
9424 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009425 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009426 }
9427 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009428
Dianne Hackborn25994b42009-09-04 14:21:19 -07009429 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009430 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009431 "Wallpaper animation!");
9432 switch (transit) {
9433 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9434 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9435 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9436 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9437 break;
9438 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9439 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9440 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9441 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9442 break;
9443 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009444 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009445 "New transit: " + transit);
9446 } else if (oldWallpaper != null) {
9447 // We are transitioning from an activity with
9448 // a wallpaper to one without.
9449 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009450 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009451 "New transit away from wallpaper: " + transit);
9452 } else if (mWallpaperTarget != null) {
9453 // We are transitioning from an activity without
9454 // a wallpaper to now showing the wallpaper
9455 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009456 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009457 "New transit into wallpaper: " + transit);
9458 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009459
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009460 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9461 mLastEnterAnimToken = animToken;
9462 mLastEnterAnimParams = animLp;
9463 } else if (mLastEnterAnimParams != null) {
9464 animLp = mLastEnterAnimParams;
9465 mLastEnterAnimToken = null;
9466 mLastEnterAnimParams = null;
9467 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009468
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009469 // If all closing windows are obscured, then there is
9470 // no need to do an animation. This is the case, for
9471 // example, when this transition is being done behind
9472 // the lock screen.
9473 if (!mPolicy.allowAppAnimationsLw()) {
9474 animLp = null;
9475 }
9476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477 NN = mOpeningApps.size();
9478 for (i=0; i<NN; i++) {
9479 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009480 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009481 "Now opening app" + wtoken);
9482 wtoken.reportedVisible = false;
9483 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009484 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009485 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009486 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009487 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009488 wtoken.showAllWindowsLocked();
9489 }
9490 NN = mClosingApps.size();
9491 for (i=0; i<NN; i++) {
9492 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009493 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 "Now closing app" + wtoken);
9495 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009496 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009497 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009498 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009499 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 // Force the allDrawn flag, because we want to start
9501 // this guy's animations regardless of whether it's
9502 // gotten drawn.
9503 wtoken.allDrawn = true;
9504 }
9505
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009506 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009508 mOpeningApps.clear();
9509 mClosingApps.clear();
9510
9511 // This has changed the visibility of windows, so perform
9512 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009513 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009515 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9516 assignLayersLocked();
9517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009519 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009520 }
9521 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009522
Dianne Hackborn16064f92010-03-25 00:47:24 -07009523 int adjResult = 0;
9524
Dianne Hackborna8f60182009-09-01 19:01:50 -07009525 if (!animating && mAppTransitionRunning) {
9526 // We have finished the animation of an app transition. To do
9527 // this, we have delayed a lot of operations like showing and
9528 // hiding apps, moving apps in Z-order, etc. The app token list
9529 // reflects the correct Z-order, but the window list may now
9530 // be out of sync with it. So here we will just rebuild the
9531 // entire app window list. Fun!
9532 mAppTransitionRunning = false;
9533 // Clear information about apps that were moving.
9534 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009535
Dianne Hackborna8f60182009-09-01 19:01:50 -07009536 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009537 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009538 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009539 moveInputMethodWindowsIfNeededLocked(false);
9540 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009541 // Since the window list has been rebuilt, focus might
9542 // have to be recomputed since the actual order of windows
9543 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009544 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009545 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009546
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009547 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009548 // At this point, there was a window with a wallpaper that
9549 // was force hiding other windows behind it, but now it
9550 // is going away. This may be simple -- just animate
9551 // away the wallpaper and its window -- or it may be
9552 // hard -- the wallpaper now needs to be shown behind
9553 // something that was hidden.
9554 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009555 if (mLowerWallpaperTarget != null
9556 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009557 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009558 "wallpaperForceHiding changed with lower="
9559 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009560 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009561 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
9562 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
9563 if (mLowerWallpaperTarget.mAppToken.hidden) {
9564 // The lower target has become hidden before we
9565 // actually started the animation... let's completely
9566 // re-evaluate everything.
9567 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009568 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009569 }
9570 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07009571 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009572 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009573 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009574 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009575 + " NEW: " + mWallpaperTarget
9576 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009577 if (mLowerWallpaperTarget == null) {
9578 // Whoops, we don't need a special wallpaper animation.
9579 // Clear them out.
9580 forceHiding = false;
9581 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009582 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009583 if (w.mSurface != null) {
9584 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07009585 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009586 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009587 forceHiding = true;
9588 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9589 if (!w.mAnimating) {
9590 // We set the animation above so it
9591 // is not yet running.
9592 w.clearAnimation();
9593 }
9594 }
9595 }
9596 }
9597 }
9598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009599
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009600 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009601 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009602 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07009603 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009605
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009606 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009607 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009608 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009609 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009610 assignLayersLocked();
9611 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009612 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009613 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009614 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009615 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009616
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009617 if (mFocusMayChange) {
9618 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009619 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009620 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009621 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009622 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009623 }
9624
9625 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009626 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009627 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009628
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009629 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
9630 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009631
Jeff Browne33348b2010-07-15 23:54:05 -07009632 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009633 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634
9635 // THIRD LOOP: Update the surfaces of all windows.
9636
9637 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9638
9639 boolean obscured = false;
9640 boolean blurring = false;
9641 boolean dimming = false;
9642 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009643 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009644 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009645
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009646 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009648 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009649 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650
9651 boolean displayed = false;
9652 final WindowManager.LayoutParams attrs = w.mAttrs;
9653 final int attrFlags = attrs.flags;
9654
9655 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009656 // XXX NOTE: The logic here could be improved. We have
9657 // the decision about whether to resize a window separated
9658 // from whether to hide the surface. This can cause us to
9659 // resize a surface even if we are going to hide it. You
9660 // can see this by (1) holding device in landscape mode on
9661 // home screen; (2) tapping browser icon (device will rotate
9662 // to landscape; (3) tap home. The wallpaper will be resized
9663 // in step 2 but then immediately hidden, causing us to
9664 // have to resize and then redraw it again in step 3. It
9665 // would be nice to figure out how to avoid this, but it is
9666 // difficult because we do need to resize surfaces in some
9667 // cases while they are hidden such as when first showing a
9668 // window.
9669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009670 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009671 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009672 TAG, "Placing surface #" + i + " " + w.mSurface
9673 + ": new=" + w.mShownFrame + ", old="
9674 + w.mLastShownFrame);
9675
9676 boolean resize;
9677 int width, height;
9678 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9679 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9680 w.mLastRequestedHeight != w.mRequestedHeight;
9681 // for a scaled surface, we just want to use
9682 // the requested size.
9683 width = w.mRequestedWidth;
9684 height = w.mRequestedHeight;
9685 w.mLastRequestedWidth = width;
9686 w.mLastRequestedHeight = height;
9687 w.mLastShownFrame.set(w.mShownFrame);
9688 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009689 if (SHOW_TRANSACTIONS) logSurface(w,
9690 "POS " + w.mShownFrame.left
9691 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009692 w.mSurfaceX = w.mShownFrame.left;
9693 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009694 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9695 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009696 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009697 if (!recoveringMemory) {
9698 reclaimSomeSurfaceMemoryLocked(w, "position");
9699 }
9700 }
9701 } else {
9702 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9703 width = w.mShownFrame.width();
9704 height = w.mShownFrame.height();
9705 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009706 }
9707
9708 if (resize) {
9709 if (width < 1) width = 1;
9710 if (height < 1) height = 1;
9711 if (w.mSurface != null) {
9712 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009713 if (SHOW_TRANSACTIONS) logSurface(w,
9714 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009715 + w.mShownFrame.top + " SIZE "
9716 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009717 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009718 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009719 w.mSurfaceW = width;
9720 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009722 w.mSurfaceX = w.mShownFrame.left;
9723 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009724 w.mSurface.setPosition(w.mShownFrame.left,
9725 w.mShownFrame.top);
9726 } catch (RuntimeException e) {
9727 // If something goes wrong with the surface (such
9728 // as running out of memory), don't take down the
9729 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009730 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731 + "size=(" + width + "x" + height
9732 + "), pos=(" + w.mShownFrame.left
9733 + "," + w.mShownFrame.top + ")", e);
9734 if (!recoveringMemory) {
9735 reclaimSomeSurfaceMemoryLocked(w, "size");
9736 }
9737 }
9738 }
9739 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009740 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 w.mContentInsetsChanged =
9742 !w.mLastContentInsets.equals(w.mContentInsets);
9743 w.mVisibleInsetsChanged =
9744 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009745 boolean configChanged =
9746 w.mConfiguration != mCurConfiguration
9747 && (w.mConfiguration == null
9748 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009749 if (DEBUG_CONFIGURATION && configChanged) {
9750 Slog.v(TAG, "Win " + w + " config changed: "
9751 + mCurConfiguration);
9752 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009753 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009754 + ": configChanged=" + configChanged
9755 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -07009756 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009758 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009759 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009760 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009761 w.mLastFrame.set(w.mFrame);
9762 w.mLastContentInsets.set(w.mContentInsets);
9763 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009764 // If the screen is currently frozen, then keep
9765 // it frozen until this window draws at its new
9766 // orientation.
9767 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009768 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009769 "Resizing while display frozen: " + w);
9770 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009771 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009772 mWindowsFreezingScreen = true;
9773 // XXX should probably keep timeout from
9774 // when we first froze the display.
9775 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9776 mH.sendMessageDelayed(mH.obtainMessage(
9777 H.WINDOW_FREEZE_TIMEOUT), 2000);
9778 }
9779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009780 // If the orientation is changing, then we need to
9781 // hold off on unfreezing the display until this
9782 // window has been redrawn; to do that, we need
9783 // to go through the process of getting informed
9784 // by the application when it has finished drawing.
9785 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009786 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009787 "Orientation start waiting for draw in "
9788 + w + ", surface " + w.mSurface);
9789 w.mDrawPending = true;
9790 w.mCommitDrawPending = false;
9791 w.mReadyToShow = false;
9792 if (w.mAppToken != null) {
9793 w.mAppToken.allDrawn = false;
9794 }
9795 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009796 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 "Resizing window " + w + " to " + w.mFrame);
9798 mResizingWindows.add(w);
9799 } else if (w.mOrientationChanging) {
9800 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009801 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 "Orientation not waiting for draw in "
9803 + w + ", surface " + w.mSurface);
9804 w.mOrientationChanging = false;
9805 }
9806 }
9807 }
9808
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009809 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810 if (!w.mLastHidden) {
9811 //dump();
9812 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009813 if (SHOW_TRANSACTIONS) logSurface(w,
9814 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009816 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 try {
9818 w.mSurface.hide();
9819 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009820 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009821 }
9822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009823 }
9824 // If we are waiting for this window to handle an
9825 // orientation change, well, it is hidden, so
9826 // doesn't really matter. Note that this does
9827 // introduce a potential glitch if the window
9828 // becomes unhidden before it has drawn for the
9829 // new orientation.
9830 if (w.mOrientationChanging) {
9831 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009832 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833 "Orientation change skips hidden " + w);
9834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009835 } else if (w.mLastLayer != w.mAnimLayer
9836 || w.mLastAlpha != w.mShownAlpha
9837 || w.mLastDsDx != w.mDsDx
9838 || w.mLastDtDx != w.mDtDx
9839 || w.mLastDsDy != w.mDsDy
9840 || w.mLastDtDy != w.mDtDy
9841 || w.mLastHScale != w.mHScale
9842 || w.mLastVScale != w.mVScale
9843 || w.mLastHidden) {
9844 displayed = true;
9845 w.mLastAlpha = w.mShownAlpha;
9846 w.mLastLayer = w.mAnimLayer;
9847 w.mLastDsDx = w.mDsDx;
9848 w.mLastDtDx = w.mDtDx;
9849 w.mLastDsDy = w.mDsDy;
9850 w.mLastDtDy = w.mDtDy;
9851 w.mLastHScale = w.mHScale;
9852 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009853 if (SHOW_TRANSACTIONS) logSurface(w,
9854 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009855 + " matrix=[" + (w.mDsDx*w.mHScale)
9856 + "," + (w.mDtDx*w.mVScale)
9857 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009858 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 if (w.mSurface != null) {
9860 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009861 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009863 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 w.mSurface.setLayer(w.mAnimLayer);
9865 w.mSurface.setMatrix(
9866 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
9867 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
9868 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009869 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009870 if (!recoveringMemory) {
9871 reclaimSomeSurfaceMemoryLocked(w, "update");
9872 }
9873 }
9874 }
9875
9876 if (w.mLastHidden && !w.mDrawPending
9877 && !w.mCommitDrawPending
9878 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009879 if (SHOW_TRANSACTIONS) logSurface(w,
9880 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009881 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 + " during relayout");
9883 if (showSurfaceRobustlyLocked(w)) {
9884 w.mHasDrawn = true;
9885 w.mLastHidden = false;
9886 } else {
9887 w.mOrientationChanging = false;
9888 }
9889 }
9890 if (w.mSurface != null) {
9891 w.mToken.hasVisible = true;
9892 }
9893 } else {
9894 displayed = true;
9895 }
9896
9897 if (displayed) {
9898 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08009899 if (attrs.width == LayoutParams.MATCH_PARENT
9900 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 covered = true;
9902 }
9903 }
9904 if (w.mOrientationChanging) {
9905 if (w.mDrawPending || w.mCommitDrawPending) {
9906 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009907 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009908 "Orientation continue waiting for draw in " + w);
9909 } else {
9910 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009911 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 "Orientation change complete in " + w);
9913 }
9914 }
9915 w.mToken.hasVisible = true;
9916 }
9917 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009918 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009919 "Orientation change skips hidden " + w);
9920 w.mOrientationChanging = false;
9921 }
9922
9923 final boolean canBeSeen = w.isDisplayedLw();
9924
9925 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
9926 focusDisplayed = true;
9927 }
9928
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07009929 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009932 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 if (w.mSurface != null) {
9934 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
9935 holdScreen = w.mSession;
9936 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009937 if (!syswin && w.mAttrs.screenBrightness >= 0
9938 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 screenBrightness = w.mAttrs.screenBrightness;
9940 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009941 if (!syswin && w.mAttrs.buttonBrightness >= 0
9942 && buttonBrightness < 0) {
9943 buttonBrightness = w.mAttrs.buttonBrightness;
9944 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05009945 if (canBeSeen
9946 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
9947 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
9948 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009949 syswin = true;
9950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009952
Dianne Hackborn25994b42009-09-04 14:21:19 -07009953 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
9954 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009955 // This window completely covers everything behind it,
9956 // so we want to leave all of them as unblurred (for
9957 // performance reasons).
9958 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009959 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009960 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009961 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009962 obscured = true;
9963 if (mBackgroundFillerSurface == null) {
9964 try {
9965 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009966 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009967 0, dw, dh,
9968 PixelFormat.OPAQUE,
9969 Surface.FX_SURFACE_NORMAL);
9970 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009971 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009972 }
9973 }
9974 try {
9975 mBackgroundFillerSurface.setPosition(0, 0);
9976 mBackgroundFillerSurface.setSize(dw, dh);
9977 // Using the same layer as Dim because they will never be shown at the
9978 // same time.
9979 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
9980 mBackgroundFillerSurface.show();
9981 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009982 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009983 }
9984 backgroundFillerShown = true;
9985 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009986 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009988 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009989 + ": blurring=" + blurring
9990 + " obscured=" + obscured
9991 + " displayed=" + displayed);
9992 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
9993 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009994 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009996 if (mDimAnimator == null) {
9997 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009999 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010000 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010002 }
10003 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10004 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010005 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010007 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010008 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 + mBlurSurface + ": CREATE");
10010 try {
Romain Guy06882f82009-06-10 13:36:04 -070010011 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010012 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010013 -1, 16, 16,
10014 PixelFormat.OPAQUE,
10015 Surface.FX_SURFACE_BLUR);
10016 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010017 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 }
10019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010021 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10022 + mBlurSurface + ": pos=(0,0) (" +
10023 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010024 mBlurSurface.setPosition(0, 0);
10025 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010026 mBlurSurface.setLayer(w.mAnimLayer-2);
10027 if (!mBlurShown) {
10028 try {
10029 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10030 + mBlurSurface + ": SHOW");
10031 mBlurSurface.show();
10032 } catch (RuntimeException e) {
10033 Slog.w(TAG, "Failure showing blur surface", e);
10034 }
10035 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 }
10037 }
10038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 }
10040 }
10041 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010042
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010043 if (obscuredChanged && mWallpaperTarget == w) {
10044 // This is the wallpaper target and its obscured state
10045 // changed... make sure the current wallaper's visibility
10046 // has been updated accordingly.
10047 updateWallpaperVisibilityLocked();
10048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010050
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010051 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10052 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010053 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010054 try {
10055 mBackgroundFillerSurface.hide();
10056 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010057 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010058 }
10059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010060
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010061 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010062 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10063 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010064 }
Romain Guy06882f82009-06-10 13:36:04 -070010065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010066 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010067 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010068 + ": HIDE");
10069 try {
10070 mBlurSurface.hide();
10071 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010072 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 }
10074 mBlurShown = false;
10075 }
10076
Joe Onorato8a9b2202010-02-26 18:56:32 -080010077 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010078 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010079 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 }
10081
Jeff Browne33348b2010-07-15 23:54:05 -070010082 mInputMonitor.updateInputWindowsLw();
10083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010085
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010086 if (mWatermark != null) {
10087 mWatermark.drawIfNeeded();
10088 }
10089
Joe Onorato8a9b2202010-02-26 18:56:32 -080010090 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 "With display frozen, orientationChangeComplete="
10092 + orientationChangeComplete);
10093 if (orientationChangeComplete) {
10094 if (mWindowsFreezingScreen) {
10095 mWindowsFreezingScreen = false;
10096 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10097 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010098 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010099 }
Romain Guy06882f82009-06-10 13:36:04 -070010100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010101 i = mResizingWindows.size();
10102 if (i > 0) {
10103 do {
10104 i--;
10105 WindowState win = mResizingWindows.get(i);
10106 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010107 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10108 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010109 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010110 boolean configChanged =
10111 win.mConfiguration != mCurConfiguration
10112 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010113 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10114 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10115 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010116 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010117 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010118 + " / " + mCurConfiguration + " / 0x"
10119 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010120 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010121 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010122 win.mClient.resized(win.mFrame.width(),
10123 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010124 win.mLastVisibleInsets, win.mDrawPending,
10125 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 win.mContentInsetsChanged = false;
10127 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010128 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 } catch (RemoteException e) {
10130 win.mOrientationChanging = false;
10131 }
10132 } while (i > 0);
10133 mResizingWindows.clear();
10134 }
Romain Guy06882f82009-06-10 13:36:04 -070010135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010136 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010137 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010138 i = mDestroySurface.size();
10139 if (i > 0) {
10140 do {
10141 i--;
10142 WindowState win = mDestroySurface.get(i);
10143 win.mDestroying = false;
10144 if (mInputMethodWindow == win) {
10145 mInputMethodWindow = null;
10146 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010147 if (win == mWallpaperTarget) {
10148 wallpaperDestroyed = true;
10149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010150 win.destroySurfaceLocked();
10151 } while (i > 0);
10152 mDestroySurface.clear();
10153 }
10154
10155 // Time to remove any exiting tokens?
10156 for (i=mExitingTokens.size()-1; i>=0; i--) {
10157 WindowToken token = mExitingTokens.get(i);
10158 if (!token.hasVisible) {
10159 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010160 if (token.windowType == TYPE_WALLPAPER) {
10161 mWallpaperTokens.remove(token);
10162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010163 }
10164 }
10165
10166 // Time to remove any exiting applications?
10167 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10168 AppWindowToken token = mExitingAppTokens.get(i);
10169 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010170 // Make sure there is no animation running on this token,
10171 // so any windows associated with it will be removed as
10172 // soon as their animations are complete
10173 token.animation = null;
10174 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010175 mAppTokens.remove(token);
10176 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010177 if (mLastEnterAnimToken == token) {
10178 mLastEnterAnimToken = null;
10179 mLastEnterAnimParams = null;
10180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 }
10182 }
10183
Dianne Hackborna8f60182009-09-01 19:01:50 -070010184 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010185
Dianne Hackborna8f60182009-09-01 19:01:50 -070010186 if (!animating && mAppTransitionRunning) {
10187 // We have finished the animation of an app transition. To do
10188 // this, we have delayed a lot of operations like showing and
10189 // hiding apps, moving apps in Z-order, etc. The app token list
10190 // reflects the correct Z-order, but the window list may now
10191 // be out of sync with it. So here we will just rebuild the
10192 // entire app window list. Fun!
10193 mAppTransitionRunning = false;
10194 needRelayout = true;
10195 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010196 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010197 // Clear information about apps that were moving.
10198 mToBottomApps.clear();
10199 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 if (focusDisplayed) {
10202 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10203 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010204 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010205 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010206 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010207 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010208 requestAnimationLocked(0);
10209 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010210 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10211 }
Jeff Browneb857f12010-07-16 10:06:33 -070010212
Jeff Browne33348b2010-07-15 23:54:05 -070010213 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010214
Jeff Brown8e03b752010-06-13 19:16:55 -070010215 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010216 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10217 mPowerManager.setScreenBrightnessOverride(-1);
10218 } else {
10219 mPowerManager.setScreenBrightnessOverride((int)
10220 (screenBrightness * Power.BRIGHTNESS_ON));
10221 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010222 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10223 mPowerManager.setButtonBrightnessOverride(-1);
10224 } else {
10225 mPowerManager.setButtonBrightnessOverride((int)
10226 (buttonBrightness * Power.BRIGHTNESS_ON));
10227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010228 if (holdScreen != mHoldingScreenOn) {
10229 mHoldingScreenOn = holdScreen;
10230 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10231 mH.sendMessage(m);
10232 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010233
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010234 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010235 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010236 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10237 LocalPowerManager.BUTTON_EVENT, true);
10238 mTurnOnScreen = false;
10239 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010240
10241 // Check to see if we are now in a state where the screen should
10242 // be enabled, because the window obscured flags have changed.
10243 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010245
10246 /**
10247 * Must be called with the main window manager lock held.
10248 */
10249 void setHoldScreenLocked(boolean holding) {
10250 boolean state = mHoldingScreenWakeLock.isHeld();
10251 if (holding != state) {
10252 if (holding) {
10253 mHoldingScreenWakeLock.acquire();
10254 } else {
10255 mPolicy.screenOnStoppedLw();
10256 mHoldingScreenWakeLock.release();
10257 }
10258 }
10259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260
10261 void requestAnimationLocked(long delay) {
10262 if (!mAnimationPending) {
10263 mAnimationPending = true;
10264 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10265 }
10266 }
Romain Guy06882f82009-06-10 13:36:04 -070010267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 /**
10269 * Have the surface flinger show a surface, robustly dealing with
10270 * error conditions. In particular, if there is not enough memory
10271 * to show the surface, then we will try to get rid of other surfaces
10272 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010273 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 * @return Returns true if the surface was successfully shown.
10275 */
10276 boolean showSurfaceRobustlyLocked(WindowState win) {
10277 try {
10278 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010279 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010280 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010281 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010282 if (DEBUG_VISIBILITY) Slog.v(TAG,
10283 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010284 win.mTurnOnScreen = false;
10285 mTurnOnScreen = true;
10286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 }
10288 return true;
10289 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010290 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010291 }
Romain Guy06882f82009-06-10 13:36:04 -070010292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 return false;
10296 }
Romain Guy06882f82009-06-10 13:36:04 -070010297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10299 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010300
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010301 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 if (mForceRemoves == null) {
10305 mForceRemoves = new ArrayList<WindowState>();
10306 }
Romain Guy06882f82009-06-10 13:36:04 -070010307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 long callingIdentity = Binder.clearCallingIdentity();
10309 try {
10310 // There was some problem... first, do a sanity check of the
10311 // window list to make sure we haven't left any dangling surfaces
10312 // around.
10313 int N = mWindows.size();
10314 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010315 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010317 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 if (ws.mSurface != null) {
10319 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010320 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 + ws + " surface=" + ws.mSurface
10322 + " token=" + win.mToken
10323 + " pid=" + ws.mSession.mPid
10324 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010325 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010326 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010327 ws.mSurface = null;
10328 mForceRemoves.add(ws);
10329 i--;
10330 N--;
10331 leakedSurface = true;
10332 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010333 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 + ws + " surface=" + ws.mSurface
10335 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010336 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010337 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010338 ws.mSurface = null;
10339 leakedSurface = true;
10340 }
10341 }
10342 }
Romain Guy06882f82009-06-10 13:36:04 -070010343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010344 boolean killedApps = false;
10345 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010346 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 SparseIntArray pidCandidates = new SparseIntArray();
10348 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010349 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 if (ws.mSurface != null) {
10351 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10352 }
10353 }
10354 if (pidCandidates.size() > 0) {
10355 int[] pids = new int[pidCandidates.size()];
10356 for (int i=0; i<pids.length; i++) {
10357 pids[i] = pidCandidates.keyAt(i);
10358 }
10359 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010360 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 killedApps = true;
10362 }
10363 } catch (RemoteException e) {
10364 }
10365 }
10366 }
Romain Guy06882f82009-06-10 13:36:04 -070010367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010368 if (leakedSurface || killedApps) {
10369 // We managed to reclaim some memory, so get rid of the trouble
10370 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010371 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010373 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010374 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010375 win.mSurface = null;
10376 }
Romain Guy06882f82009-06-10 13:36:04 -070010377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 try {
10379 win.mClient.dispatchGetNewSurface();
10380 } catch (RemoteException e) {
10381 }
10382 }
10383 } finally {
10384 Binder.restoreCallingIdentity(callingIdentity);
10385 }
10386 }
Romain Guy06882f82009-06-10 13:36:04 -070010387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010388 private boolean updateFocusedWindowLocked(int mode) {
10389 WindowState newFocus = computeFocusedWindowLocked();
10390 if (mCurrentFocus != newFocus) {
10391 // This check makes sure that we don't already have the focus
10392 // change message pending.
10393 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10394 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010395 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010396 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10397 final WindowState oldFocus = mCurrentFocus;
10398 mCurrentFocus = newFocus;
10399 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010401 final WindowState imWindow = mInputMethodWindow;
10402 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010403 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010405 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10406 mLayoutNeeded = true;
10407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010408 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
10409 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010410 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10411 // Client will do the layout, but we need to assign layers
10412 // for handleNewWindowLocked() below.
10413 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010414 }
10415 }
Jeff Brown349703e2010-06-22 01:27:15 -070010416
10417 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10418 // If we defer assigning layers, then the caller is responsible for
10419 // doing this part.
10420 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010422 return true;
10423 }
10424 return false;
10425 }
Jeff Brown349703e2010-06-22 01:27:15 -070010426
10427 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010428 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010430
10431 private WindowState computeFocusedWindowLocked() {
10432 WindowState result = null;
10433 WindowState win;
10434
10435 int i = mWindows.size() - 1;
10436 int nextAppIndex = mAppTokens.size()-1;
10437 WindowToken nextApp = nextAppIndex >= 0
10438 ? mAppTokens.get(nextAppIndex) : null;
10439
10440 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010441 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010442
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010444 TAG, "Looking for focus: " + i
10445 + " = " + win
10446 + ", flags=" + win.mAttrs.flags
10447 + ", canReceive=" + win.canReceiveKeys());
10448
10449 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 // If this window's application has been removed, just skip it.
10452 if (thisApp != null && thisApp.removed) {
10453 i--;
10454 continue;
10455 }
Romain Guy06882f82009-06-10 13:36:04 -070010456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 // If there is a focused app, don't allow focus to go to any
10458 // windows below it. If this is an application window, step
10459 // through the app tokens until we find its app.
10460 if (thisApp != null && nextApp != null && thisApp != nextApp
10461 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10462 int origAppIndex = nextAppIndex;
10463 while (nextAppIndex > 0) {
10464 if (nextApp == mFocusedApp) {
10465 // Whoops, we are below the focused app... no focus
10466 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010467 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010468 TAG, "Reached focused app: " + mFocusedApp);
10469 return null;
10470 }
10471 nextAppIndex--;
10472 nextApp = mAppTokens.get(nextAppIndex);
10473 if (nextApp == thisApp) {
10474 break;
10475 }
10476 }
10477 if (thisApp != nextApp) {
10478 // Uh oh, the app token doesn't exist! This shouldn't
10479 // happen, but if it does we can get totally hosed...
10480 // so restart at the original app.
10481 nextAppIndex = origAppIndex;
10482 nextApp = mAppTokens.get(nextAppIndex);
10483 }
10484 }
10485
10486 // Dispatch to this window if it is wants key events.
10487 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010488 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 TAG, "Found focus @ " + i + " = " + win);
10490 result = win;
10491 break;
10492 }
10493
10494 i--;
10495 }
10496
10497 return result;
10498 }
10499
10500 private void startFreezingDisplayLocked() {
10501 if (mDisplayFrozen) {
10502 return;
10503 }
Romain Guy06882f82009-06-10 13:36:04 -070010504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010505 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010507 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010508 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010509 if (mFreezeGcPending != 0) {
10510 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010511 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010512 mH.removeMessages(H.FORCE_GC);
10513 Runtime.getRuntime().gc();
10514 mFreezeGcPending = now;
10515 }
10516 } else {
10517 mFreezeGcPending = now;
10518 }
Romain Guy06882f82009-06-10 13:36:04 -070010519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010520 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010521
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010522 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010523
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010524 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10525 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010526 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 mAppTransitionReady = true;
10528 }
Romain Guy06882f82009-06-10 13:36:04 -070010529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 if (PROFILE_ORIENTATION) {
10531 File file = new File("/data/system/frozen");
10532 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10533 }
10534 Surface.freezeDisplay(0);
10535 }
Romain Guy06882f82009-06-10 13:36:04 -070010536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010537 private void stopFreezingDisplayLocked() {
10538 if (!mDisplayFrozen) {
10539 return;
10540 }
Romain Guy06882f82009-06-10 13:36:04 -070010541
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010542 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
10543 return;
10544 }
10545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 mDisplayFrozen = false;
10547 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
10548 if (PROFILE_ORIENTATION) {
10549 Debug.stopMethodTracing();
10550 }
10551 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070010552
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010553 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010554
Christopher Tateb696aee2010-04-02 19:08:30 -070010555 // While the display is frozen we don't re-compute the orientation
10556 // to avoid inconsistent states. However, something interesting
10557 // could have actually changed during that time so re-evaluate it
10558 // now to catch that.
10559 if (updateOrientationFromAppTokensLocked()) {
10560 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10561 }
10562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010563 // A little kludge: a lot could have happened while the
10564 // display was frozen, so now that we are coming back we
10565 // do a gc so that any remote references the system
10566 // processes holds on others can be released if they are
10567 // no longer needed.
10568 mH.removeMessages(H.FORCE_GC);
10569 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10570 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010572 mScreenFrozenLock.release();
10573 }
Romain Guy06882f82009-06-10 13:36:04 -070010574
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010575 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10576 DisplayMetrics dm) {
10577 if (index < tokens.length) {
10578 String str = tokens[index];
10579 if (str != null && str.length() > 0) {
10580 try {
10581 int val = Integer.parseInt(str);
10582 return val;
10583 } catch (Exception e) {
10584 }
10585 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010586 }
10587 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10588 return defDps;
10589 }
10590 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10591 return val;
10592 }
10593
10594 class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010595 final String[] mTokens;
10596 final String mText;
10597 final Paint mTextPaint;
10598 final int mTextWidth;
10599 final int mTextHeight;
10600 final int mTextAscent;
10601 final int mTextDescent;
10602 final int mDeltaX;
10603 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010604
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010605 Surface mSurface;
10606 int mLastDW;
10607 int mLastDH;
10608 boolean mDrawNeeded;
10609
10610 Watermark(SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010611 final DisplayMetrics dm = new DisplayMetrics();
10612 mDisplay.getMetrics(dm);
10613
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010614 if (false) {
10615 Log.i(TAG, "*********************** WATERMARK");
10616 for (int i=0; i<tokens.length; i++) {
10617 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
10618 }
10619 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010620
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010621 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010622
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010623 StringBuilder builder = new StringBuilder(32);
10624 int len = mTokens[0].length();
10625 len = len & ~1;
10626 for (int i=0; i<len; i+=2) {
10627 int c1 = mTokens[0].charAt(i);
10628 int c2 = mTokens[0].charAt(i+1);
10629 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
10630 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
10631 else c1 -= '0';
10632 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
10633 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
10634 else c2 -= '0';
10635 builder.append((char)(255-((c1*16)+c2)));
10636 }
10637 mText = builder.toString();
10638 if (false) {
10639 Log.i(TAG, "Final text: " + mText);
10640 }
10641
10642 int fontSize = getPropertyInt(tokens, 1,
10643 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
10644
10645 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
10646 mTextPaint.setTextSize(fontSize);
10647 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
10648
10649 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
10650 mTextWidth = (int)mTextPaint.measureText(mText);
10651 mTextAscent = fm.ascent;
10652 mTextDescent = fm.descent;
10653 mTextHeight = fm.descent - fm.ascent;
10654
10655 mDeltaX = getPropertyInt(tokens, 2,
10656 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
10657 mDeltaY = getPropertyInt(tokens, 3,
10658 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
10659 int shadowColor = getPropertyInt(tokens, 4,
10660 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
10661 int color = getPropertyInt(tokens, 5,
10662 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
10663 int shadowRadius = getPropertyInt(tokens, 6,
10664 TypedValue.COMPLEX_UNIT_PX, 7, dm);
10665 int shadowDx = getPropertyInt(tokens, 8,
10666 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10667 int shadowDy = getPropertyInt(tokens, 9,
10668 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10669
10670 mTextPaint.setColor(color);
10671 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010672
10673 try {
10674 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010675 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010676 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010677 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010678 mSurface.show();
10679 } catch (OutOfResourcesException e) {
10680 }
10681 }
10682
10683 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010684 if (mLastDW != dw || mLastDH != dh) {
10685 mLastDW = dw;
10686 mLastDH = dh;
10687 mSurface.setSize(dw, dh);
10688 mDrawNeeded = true;
10689 }
10690 }
10691
10692 void drawIfNeeded() {
10693 if (mDrawNeeded) {
10694 final int dw = mLastDW;
10695 final int dh = mLastDH;
10696
10697 mDrawNeeded = false;
10698 Rect dirty = new Rect(0, 0, dw, dh);
10699 Canvas c = null;
10700 try {
10701 c = mSurface.lockCanvas(dirty);
10702 } catch (IllegalArgumentException e) {
10703 } catch (OutOfResourcesException e) {
10704 }
10705 if (c != null) {
10706 int deltaX = mDeltaX;
10707 int deltaY = mDeltaY;
10708
10709 // deltaX shouldn't be close to a round fraction of our
10710 // x step, or else things will line up too much.
10711 int div = (dw+mTextWidth)/deltaX;
10712 int rem = (dw+mTextWidth) - (div*deltaX);
10713 int qdelta = deltaX/4;
10714 if (rem < qdelta || rem > (deltaX-qdelta)) {
10715 deltaX += deltaX/3;
10716 }
10717
10718 int y = -mTextHeight;
10719 int x = -mTextWidth;
10720 while (y < (dh+mTextHeight)) {
10721 c.drawText(mText, x, y, mTextPaint);
10722 x += deltaX;
10723 if (x >= dw) {
10724 x -= (dw+mTextWidth);
10725 y += deltaY;
10726 }
10727 }
10728 mSurface.unlockCanvasAndPost(c);
10729 }
10730 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010731 }
10732 }
10733
10734 void createWatermark() {
10735 if (mWatermark != null) {
10736 return;
10737 }
10738
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010739 File file = new File("/system/etc/setup.conf");
10740 FileInputStream in = null;
10741 try {
10742 in = new FileInputStream(file);
10743 DataInputStream ind = new DataInputStream(in);
10744 String line = ind.readLine();
10745 if (line != null) {
10746 String[] toks = line.split("%");
10747 if (toks != null && toks.length > 0) {
10748 mWatermark = new Watermark(mFxSession, toks);
10749 }
10750 }
10751 } catch (FileNotFoundException e) {
10752 } catch (IOException e) {
10753 } finally {
10754 if (in != null) {
10755 try {
10756 in.close();
10757 } catch (IOException e) {
10758 }
10759 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010760 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010761 }
10762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010763 @Override
10764 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10765 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10766 != PackageManager.PERMISSION_GRANTED) {
10767 pw.println("Permission Denial: can't dump WindowManager from from pid="
10768 + Binder.getCallingPid()
10769 + ", uid=" + Binder.getCallingUid());
10770 return;
10771 }
Romain Guy06882f82009-06-10 13:36:04 -070010772
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010773 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080010774 pw.println(" ");
10775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010776 synchronized(mWindowMap) {
10777 pw.println("Current Window Manager state:");
10778 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010779 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010780 pw.print(" Window #"); pw.print(i); pw.print(' ');
10781 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 w.dump(pw, " ");
10783 }
10784 if (mInputMethodDialogs.size() > 0) {
10785 pw.println(" ");
10786 pw.println(" Input method dialogs:");
10787 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10788 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010789 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010790 }
10791 }
10792 if (mPendingRemove.size() > 0) {
10793 pw.println(" ");
10794 pw.println(" Remove pending for:");
10795 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10796 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010797 pw.print(" Remove #"); pw.print(i); pw.print(' ');
10798 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 w.dump(pw, " ");
10800 }
10801 }
10802 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10803 pw.println(" ");
10804 pw.println(" Windows force removing:");
10805 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10806 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010807 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10808 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 w.dump(pw, " ");
10810 }
10811 }
10812 if (mDestroySurface.size() > 0) {
10813 pw.println(" ");
10814 pw.println(" Windows waiting to destroy their surface:");
10815 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10816 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010817 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
10818 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010819 w.dump(pw, " ");
10820 }
10821 }
10822 if (mLosingFocus.size() > 0) {
10823 pw.println(" ");
10824 pw.println(" Windows losing focus:");
10825 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10826 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010827 pw.print(" Losing #"); pw.print(i); pw.print(' ');
10828 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 w.dump(pw, " ");
10830 }
10831 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010832 if (mResizingWindows.size() > 0) {
10833 pw.println(" ");
10834 pw.println(" Windows waiting to resize:");
10835 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10836 WindowState w = mResizingWindows.get(i);
10837 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
10838 pw.print(w); pw.println(":");
10839 w.dump(pw, " ");
10840 }
10841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 if (mSessions.size() > 0) {
10843 pw.println(" ");
10844 pw.println(" All active sessions:");
10845 Iterator<Session> it = mSessions.iterator();
10846 while (it.hasNext()) {
10847 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010848 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010849 s.dump(pw, " ");
10850 }
10851 }
10852 if (mTokenMap.size() > 0) {
10853 pw.println(" ");
10854 pw.println(" All tokens:");
10855 Iterator<WindowToken> it = mTokenMap.values().iterator();
10856 while (it.hasNext()) {
10857 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010858 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010859 token.dump(pw, " ");
10860 }
10861 }
10862 if (mTokenList.size() > 0) {
10863 pw.println(" ");
10864 pw.println(" Window token list:");
10865 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010866 pw.print(" #"); pw.print(i); pw.print(": ");
10867 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010868 }
10869 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010870 if (mWallpaperTokens.size() > 0) {
10871 pw.println(" ");
10872 pw.println(" Wallpaper tokens:");
10873 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10874 WindowToken token = mWallpaperTokens.get(i);
10875 pw.print(" Wallpaper #"); pw.print(i);
10876 pw.print(' '); pw.print(token); pw.println(':');
10877 token.dump(pw, " ");
10878 }
10879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 if (mAppTokens.size() > 0) {
10881 pw.println(" ");
10882 pw.println(" Application tokens in Z order:");
10883 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010884 pw.print(" App #"); pw.print(i); pw.print(": ");
10885 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010886 }
10887 }
10888 if (mFinishedStarting.size() > 0) {
10889 pw.println(" ");
10890 pw.println(" Finishing start of application tokens:");
10891 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10892 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010893 pw.print(" Finished Starting #"); pw.print(i);
10894 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010895 token.dump(pw, " ");
10896 }
10897 }
10898 if (mExitingTokens.size() > 0) {
10899 pw.println(" ");
10900 pw.println(" Exiting tokens:");
10901 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10902 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010903 pw.print(" Exiting #"); pw.print(i);
10904 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 token.dump(pw, " ");
10906 }
10907 }
10908 if (mExitingAppTokens.size() > 0) {
10909 pw.println(" ");
10910 pw.println(" Exiting application tokens:");
10911 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10912 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010913 pw.print(" Exiting App #"); pw.print(i);
10914 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 token.dump(pw, " ");
10916 }
10917 }
10918 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010919 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10920 pw.print(" mLastFocus="); pw.println(mLastFocus);
10921 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10922 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
10923 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010924 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010925 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10926 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10927 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10928 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010929 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10930 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10931 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010932 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10933 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
10934 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
10935 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010936 if (mDimAnimator != null) {
10937 mDimAnimator.printTo(pw);
10938 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080010939 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010940 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010941 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070010942 pw.print(mInputMethodAnimLayerAdjustment);
10943 pw.print(" mWallpaperAnimLayerAdjustment=");
10944 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010945 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10946 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010947 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
10948 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010949 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
10950 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010951 pw.print(" mRotation="); pw.print(mRotation);
10952 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
10953 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
10954 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
10955 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10956 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
10957 pw.print(" mNextAppTransition=0x");
10958 pw.print(Integer.toHexString(mNextAppTransition));
10959 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070010960 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010961 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010962 if (mNextAppTransitionPackage != null) {
10963 pw.print(" mNextAppTransitionPackage=");
10964 pw.print(mNextAppTransitionPackage);
10965 pw.print(", mNextAppTransitionEnter=0x");
10966 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10967 pw.print(", mNextAppTransitionExit=0x");
10968 pw.print(Integer.toHexString(mNextAppTransitionExit));
10969 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010970 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
10971 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010972 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
10973 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
10974 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
10975 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010976 if (mOpeningApps.size() > 0) {
10977 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10978 }
10979 if (mClosingApps.size() > 0) {
10980 pw.print(" mClosingApps="); pw.println(mClosingApps);
10981 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010982 if (mToTopApps.size() > 0) {
10983 pw.print(" mToTopApps="); pw.println(mToTopApps);
10984 }
10985 if (mToBottomApps.size() > 0) {
10986 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
10987 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010988 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
10989 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010990 }
10991 }
10992
Jeff Brown349703e2010-06-22 01:27:15 -070010993 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994 public void monitor() {
10995 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050010996 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010997 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010998
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010999 /**
11000 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011001 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011002 */
11003 private static class DimAnimator {
11004 Surface mDimSurface;
11005 boolean mDimShown = false;
11006 float mDimCurrentAlpha;
11007 float mDimTargetAlpha;
11008 float mDimDeltaPerMs;
11009 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011010
11011 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011012
11013 DimAnimator (SurfaceSession session) {
11014 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011015 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011016 + mDimSurface + ": CREATE");
11017 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011018 mDimSurface = new Surface(session, 0,
11019 "DimSurface",
11020 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011021 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011022 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011023 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011024 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011025 }
11026 }
11027 }
11028
11029 /**
11030 * Show the dim surface.
11031 */
11032 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011033 if (!mDimShown) {
11034 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11035 dw + "x" + dh + ")");
11036 mDimShown = true;
11037 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011038 mLastDimWidth = dw;
11039 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011040 mDimSurface.setPosition(0, 0);
11041 mDimSurface.setSize(dw, dh);
11042 mDimSurface.show();
11043 } catch (RuntimeException e) {
11044 Slog.w(TAG, "Failure showing dim surface", e);
11045 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011046 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11047 mLastDimWidth = dw;
11048 mLastDimHeight = dh;
11049 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011050 }
11051 }
11052
11053 /**
11054 * Set's the dim surface's layer and update dim parameters that will be used in
11055 * {@link updateSurface} after all windows are examined.
11056 */
11057 void updateParameters(WindowState w, long currentTime) {
11058 mDimSurface.setLayer(w.mAnimLayer-1);
11059
11060 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011061 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011062 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011063 if (mDimTargetAlpha != target) {
11064 // If the desired dim level has changed, then
11065 // start an animation to it.
11066 mLastDimAnimTime = currentTime;
11067 long duration = (w.mAnimating && w.mAnimation != null)
11068 ? w.mAnimation.computeDurationHint()
11069 : DEFAULT_DIM_DURATION;
11070 if (target > mDimTargetAlpha) {
11071 // This is happening behind the activity UI,
11072 // so we can make it run a little longer to
11073 // give a stronger impression without disrupting
11074 // the user.
11075 duration *= DIM_DURATION_MULTIPLIER;
11076 }
11077 if (duration < 1) {
11078 // Don't divide by zero
11079 duration = 1;
11080 }
11081 mDimTargetAlpha = target;
11082 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11083 }
11084 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011085
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011086 /**
11087 * Updating the surface's alpha. Returns true if the animation continues, or returns
11088 * false when the animation is finished and the dim surface is hidden.
11089 */
11090 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11091 if (!dimming) {
11092 if (mDimTargetAlpha != 0) {
11093 mLastDimAnimTime = currentTime;
11094 mDimTargetAlpha = 0;
11095 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11096 }
11097 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011098
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011099 boolean animating = false;
11100 if (mLastDimAnimTime != 0) {
11101 mDimCurrentAlpha += mDimDeltaPerMs
11102 * (currentTime-mLastDimAnimTime);
11103 boolean more = true;
11104 if (displayFrozen) {
11105 // If the display is frozen, there is no reason to animate.
11106 more = false;
11107 } else if (mDimDeltaPerMs > 0) {
11108 if (mDimCurrentAlpha > mDimTargetAlpha) {
11109 more = false;
11110 }
11111 } else if (mDimDeltaPerMs < 0) {
11112 if (mDimCurrentAlpha < mDimTargetAlpha) {
11113 more = false;
11114 }
11115 } else {
11116 more = false;
11117 }
11118
11119 // Do we need to continue animating?
11120 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011121 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011122 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11123 mLastDimAnimTime = currentTime;
11124 mDimSurface.setAlpha(mDimCurrentAlpha);
11125 animating = true;
11126 } else {
11127 mDimCurrentAlpha = mDimTargetAlpha;
11128 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011129 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011130 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11131 mDimSurface.setAlpha(mDimCurrentAlpha);
11132 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011133 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011134 + ": HIDE");
11135 try {
11136 mDimSurface.hide();
11137 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011138 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011139 }
11140 mDimShown = false;
11141 }
11142 }
11143 }
11144 return animating;
11145 }
11146
11147 public void printTo(PrintWriter pw) {
11148 pw.print(" mDimShown="); pw.print(mDimShown);
11149 pw.print(" current="); pw.print(mDimCurrentAlpha);
11150 pw.print(" target="); pw.print(mDimTargetAlpha);
11151 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11152 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11153 }
11154 }
11155
11156 /**
11157 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11158 * This is used for opening/closing transition for apps in compatible mode.
11159 */
11160 private static class FadeInOutAnimation extends Animation {
11161 int mWidth;
11162 boolean mFadeIn;
11163
11164 public FadeInOutAnimation(boolean fadeIn) {
11165 setInterpolator(new AccelerateInterpolator());
11166 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11167 mFadeIn = fadeIn;
11168 }
11169
11170 @Override
11171 protected void applyTransformation(float interpolatedTime, Transformation t) {
11172 float x = interpolatedTime;
11173 if (!mFadeIn) {
11174 x = 1.0f - x; // reverse the interpolation for fade out
11175 }
11176 if (x < 0.5) {
11177 // move the window out of the screen.
11178 t.getMatrix().setTranslate(mWidth, 0);
11179 } else {
11180 t.getMatrix().setTranslate(0, 0);// show
11181 t.setAlpha((x - 0.5f) * 2);
11182 }
11183 }
11184
11185 @Override
11186 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11187 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11188 mWidth = width;
11189 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011190
11191 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011192 public int getZAdjustment() {
11193 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011194 }
11195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011196}