blob: 6c23e37654219168c8114835c8765bd2ddfe12c5 [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;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700508 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700509
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 */
Chris Tateb8203e92010-10-12 14:23:21 -0700560 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700561 // 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();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700565 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700566
Chris Tateb8203e92010-10-12 14:23:21 -0700567 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, touchX, touchY,
568 mDataDescription, null);
569
Christopher Tatea53146c2010-09-07 11:57:52 -0700570 if (DEBUG_DRAG) {
Chris Tateb8203e92010-10-12 14:23:21 -0700571 Slog.d(TAG, "broadcasting DRAG_STARTED: " + evt);
Christopher Tatea53146c2010-09-07 11:57:52 -0700572 }
573
Christopher Tate2c095f32010-10-04 14:13:40 -0700574 final int N = mWindows.size();
575 for (int i = 0; i < N; i++) {
576 // sendDragStartedLw() clones evt for local-process dispatch
577 sendDragStartedLw(mWindows.get(i), evt);
Christopher Tatea53146c2010-09-07 11:57:52 -0700578 }
579 evt.recycle();
580 }
581
582 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
583 * designated window is potentially a drop recipient. There are race situations
584 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
585 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700586 *
587 * This method clones the 'event' parameter if it's being delivered to the same
588 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700589 */
Christopher Tate2c095f32010-10-04 14:13:40 -0700590 private void sendDragStartedLw(WindowState newWin, DragEvent event) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700591 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700592 try {
Christopher Tate2c095f32010-10-04 14:13:40 -0700593 // clone for local callees since dispatch will recycle the event
594 if (Process.myPid() == newWin.mSession.mPid) {
595 event = DragEvent.obtain(event);
596 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700597 newWin.mClient.dispatchDragEvent(event);
598 // track each window that we've notified that the drag is starting
599 mNotifiedWindows.add(newWin);
600 } catch (RemoteException e) {
601 Slog.w(TAG, "Unable to drag-start window " + newWin);
602 }
603 }
604 }
605
606 /* helper - construct and send a DRAG_STARTED event only if the window has not
607 * previously been notified, i.e. it became visible after the drag operation
608 * was begun. This is a rare case.
609 */
610 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700611 if (mDragInProgress) {
612 // If we have sent the drag-started, we needn't do so again
613 for (WindowState ws : mNotifiedWindows) {
614 if (ws == newWin) {
615 return;
616 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700617 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700618 if (DEBUG_DRAG) {
619 Slog.d(TAG, "sending DRAG_STARTED to new window " + newWin);
620 }
621 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
622 mDataDescription, null);
623 // sendDragStartedLw() clones 'event' if the window is process-local
624 sendDragStartedLw(newWin, event);
625 event.recycle();
Christopher Tatea53146c2010-09-07 11:57:52 -0700626 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700627 }
628
629 void broadcastDragEnded() {
630 if (DEBUG_DRAG) {
631 Slog.d(TAG, "broadcasting DRAG_ENDED");
632 }
633 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, 0, 0, null, null);
634 synchronized (mWindowMap) {
635 for (WindowState ws: mNotifiedWindows) {
636 try {
637 ws.mClient.dispatchDragEvent(evt);
638 } catch (RemoteException e) {
639 Slog.w(TAG, "Unable to drag-end window " + ws);
640 }
641 }
642 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700643 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700644 }
645 evt.recycle();
646 }
647
648 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700649 final int myPid = Process.myPid();
650
651 // Move the surface to the given touch
652 mSurface.openTransaction();
653 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
654 mSurface.closeTransaction();
655
656 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700657 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
658 try {
659 // have we dragged over a new window?
660 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
661 if (DEBUG_DRAG) {
662 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
663 }
664 // force DRAG_EXITED_EVENT if appropriate
665 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
666 0, 0, null, null);
667 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700668 if (myPid != mTargetWindow.mSession.mPid) {
669 evt.recycle();
670 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700671 }
672 if (touchedWin != null) {
673 if (DEBUG_DRAG) {
674 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
675 }
676 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
677 x, y, null, null);
678 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700679 if (myPid != touchedWin.mSession.mPid) {
680 evt.recycle();
681 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700682 }
683 } catch (RemoteException e) {
684 Slog.w(TAG, "can't send drag notification to windows");
685 }
686 mTargetWindow = touchedWin;
687 }
688
689 // Tell the drop target about the data, and then broadcast the drag-ended notification
690 void notifyDropLw(float x, float y) {
691 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
692 if (touchedWin != null) {
693 if (DEBUG_DRAG) {
694 Slog.d(TAG, "sending DROP to " + touchedWin);
695 }
Christopher Tate2c095f32010-10-04 14:13:40 -0700696 final int myPid = Process.myPid();
Christopher Tatea53146c2010-09-07 11:57:52 -0700697 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x, y, null, mData);
698 try {
699 touchedWin.mClient.dispatchDragEvent(evt);
700 } catch (RemoteException e) {
701 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
702 }
Christopher Tate2c095f32010-10-04 14:13:40 -0700703 if (myPid != touchedWin.mSession.mPid) {
704 evt.recycle();
705 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700706 }
707 }
708
709 // Find the visible, touch-deliverable window under the given point
710 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
711 WindowState touchedWin = null;
712 final int x = (int) xf;
713 final int y = (int) yf;
714 final ArrayList<WindowState> windows = mWindows;
715 final int N = windows.size();
716 for (int i = N - 1; i >= 0; i--) {
717 WindowState child = windows.get(i);
718 final int flags = child.mAttrs.flags;
719 if (!child.isVisibleLw()) {
720 // not visible == don't tell about drags
721 continue;
722 }
723 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
724 // not touchable == don't tell about drags
725 continue;
726 }
727 // account for the window's decor etc
728 tmpRect.set(child.mFrame);
729 if (child.mTouchableInsets == ViewTreeObserver
730 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
731 // The point is inside of the window if it is
732 // inside the frame, AND the content part of that
733 // frame that was given by the application.
734 tmpRect.left += child.mGivenContentInsets.left;
735 tmpRect.top += child.mGivenContentInsets.top;
736 tmpRect.right -= child.mGivenContentInsets.right;
737 tmpRect.bottom -= child.mGivenContentInsets.bottom;
738 } else if (child.mTouchableInsets == ViewTreeObserver
739 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
740 // The point is inside of the window if it is
741 // inside the frame, AND the visible part of that
742 // frame that was given by the application.
743 tmpRect.left += child.mGivenVisibleInsets.left;
744 tmpRect.top += child.mGivenVisibleInsets.top;
745 tmpRect.right -= child.mGivenVisibleInsets.right;
746 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
747 }
748 final int touchFlags = flags &
749 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
750 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
751 if (tmpRect.contains(x, y) || touchFlags == 0) {
752 // Found it
753 touchedWin = child;
754 break;
755 }
756 }
757
758 return touchedWin;
759 }
760 }
761
762 DragState mDragState = null;
763 private final InputHandler mDragInputHandler = new BaseInputHandler() {
764 @Override
765 public void handleMotion(MotionEvent event, Runnable finishedCallback) {
766 boolean endDrag = false;
767 final float newX = event.getRawX();
768 final float newY = event.getRawY();
769
770 try {
771 if (mDragState != null) {
772 switch (event.getAction()) {
773 case MotionEvent.ACTION_DOWN: {
774 if (DEBUG_DRAG) {
775 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
776 }
777 } break;
778
779 case MotionEvent.ACTION_MOVE: {
780 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700781 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700782 mDragState.notifyMoveLw(newX, newY);
783 }
784 } break;
785
786 case MotionEvent.ACTION_UP: {
787 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
788 + newX + "," + newY);
789 synchronized (mWindowMap) {
790 mDragState.notifyDropLw(newX, newY);
791 }
792 endDrag = true;
793 } break;
794
795 case MotionEvent.ACTION_CANCEL: {
796 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
797 endDrag = true;
798 } break;
799 }
800
801 if (endDrag) {
802 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
803 // tell all the windows that the drag has ended
804 mDragState.broadcastDragEnded();
805
806 // stop intercepting input
807 mDragState.unregister();
Chris Tate59943592010-10-11 20:33:44 -0700808 synchronized (mWindowMap) {
809 mInputMonitor.updateInputWindowsLw();
810 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700811
812 // free our resources and drop all the object references
813 mDragState.reset();
814 mDragState = null;
815 }
816 }
817 } catch (Exception e) {
818 Slog.e(TAG, "Exception caught by drag handleMotion", e);
819 } finally {
820 finishedCallback.run();
821 }
822 }
823 };
824
825 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 * Whether the UI is currently running in touch mode (not showing
827 * navigational focus because the user is directly pressing the screen).
828 */
829 boolean mInTouchMode = false;
830
831 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700832 private ArrayList<WindowChangeListener> mWindowChangeListeners =
833 new ArrayList<WindowChangeListener>();
834 private boolean mWindowsChanged = false;
835
836 public interface WindowChangeListener {
837 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700838 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840
Dianne Hackbornc485a602009-03-24 22:39:49 -0700841 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700842 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700843
844 // The frame use to limit the size of the app running in compatibility mode.
845 Rect mCompatibleScreenFrame = new Rect();
846 // The surface used to fill the outer rim of the app running in compatibility mode.
847 Surface mBackgroundFillerSurface = null;
848 boolean mBackgroundFillerShown = false;
849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 public static WindowManagerService main(Context context,
851 PowerManagerService pm, boolean haveInputMethods) {
852 WMThread thr = new WMThread(context, pm, haveInputMethods);
853 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 synchronized (thr) {
856 while (thr.mService == null) {
857 try {
858 thr.wait();
859 } catch (InterruptedException e) {
860 }
861 }
862 }
Romain Guy06882f82009-06-10 13:36:04 -0700863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return thr.mService;
865 }
Romain Guy06882f82009-06-10 13:36:04 -0700866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 static class WMThread extends Thread {
868 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 private final Context mContext;
871 private final PowerManagerService mPM;
872 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 public WMThread(Context context, PowerManagerService pm,
875 boolean haveInputMethods) {
876 super("WindowManager");
877 mContext = context;
878 mPM = pm;
879 mHaveInputMethods = haveInputMethods;
880 }
Romain Guy06882f82009-06-10 13:36:04 -0700881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 public void run() {
883 Looper.prepare();
884 WindowManagerService s = new WindowManagerService(mContext, mPM,
885 mHaveInputMethods);
886 android.os.Process.setThreadPriority(
887 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700888 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 synchronized (this) {
891 mService = s;
892 notifyAll();
893 }
Romain Guy06882f82009-06-10 13:36:04 -0700894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 Looper.loop();
896 }
897 }
898
899 static class PolicyThread extends Thread {
900 private final WindowManagerPolicy mPolicy;
901 private final WindowManagerService mService;
902 private final Context mContext;
903 private final PowerManagerService mPM;
904 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 public PolicyThread(WindowManagerPolicy policy,
907 WindowManagerService service, Context context,
908 PowerManagerService pm) {
909 super("WindowManagerPolicy");
910 mPolicy = policy;
911 mService = service;
912 mContext = context;
913 mPM = pm;
914 }
Romain Guy06882f82009-06-10 13:36:04 -0700915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 public void run() {
917 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800918 WindowManagerPolicyThread.set(this, Looper.myLooper());
919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800921 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 android.os.Process.setThreadPriority(
923 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700924 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 synchronized (this) {
928 mRunning = true;
929 notifyAll();
930 }
Romain Guy06882f82009-06-10 13:36:04 -0700931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 Looper.loop();
933 }
934 }
935
936 private WindowManagerService(Context context, PowerManagerService pm,
937 boolean haveInputMethods) {
938 mContext = context;
939 mHaveInputMethods = haveInputMethods;
940 mLimitedAlphaCompositing = context.getResources().getBoolean(
941 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 mPowerManager = pm;
944 mPowerManager.setPolicy(mPolicy);
945 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
946 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
947 "SCREEN_FROZEN");
948 mScreenFrozenLock.setReferenceCounted(false);
949
950 mActivityManager = ActivityManagerNative.getDefault();
951 mBatteryStats = BatteryStatsService.getService();
952
953 // Get persisted window scale setting
954 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
955 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
956 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
957 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700958
Jim Miller284b62e2010-06-08 14:27:42 -0700959 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
960 IntentFilter filter = new IntentFilter();
961 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
962 mContext.registerReceiver(mBroadcastReceiver, filter);
963
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700964 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
965 "KEEP_SCREEN_ON_FLAG");
966 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967
Jeff Browne33348b2010-07-15 23:54:05 -0700968 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
971 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 synchronized (thr) {
974 while (!thr.mRunning) {
975 try {
976 thr.wait();
977 } catch (InterruptedException e) {
978 }
979 }
980 }
Romain Guy06882f82009-06-10 13:36:04 -0700981
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700982 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 // Add ourself to the Watchdog monitors.
985 Watchdog.getInstance().addMonitor(this);
986 }
987
988 @Override
989 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
990 throws RemoteException {
991 try {
992 return super.onTransact(code, data, reply, flags);
993 } catch (RuntimeException e) {
994 // The window manager only throws security exceptions, so let's
995 // log all others.
996 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800997 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
999 throw e;
1000 }
1001 }
1002
Jeff Browne33348b2010-07-15 23:54:05 -07001003 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001005 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 TAG, "Adding window " + window + " at "
1007 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1008 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001009 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 }
1011
Jeff Browne33348b2010-07-15 23:54:05 -07001012 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001014 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 TAG, "Adding window " + window + " at "
1016 + i + " of " + mWindows.size() + " (before " + pos + ")");
1017 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001018 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 }
1020
1021 //This method finds out the index of a window that has the same app token as
1022 //win. used for z ordering the windows in mWindows
1023 private int findIdxBasedOnAppTokens(WindowState win) {
1024 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001025 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026 int jmax = localmWindows.size();
1027 if(jmax == 0) {
1028 return -1;
1029 }
1030 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001031 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 if(wentry.mAppToken == win.mAppToken) {
1033 return j;
1034 }
1035 }
1036 return -1;
1037 }
Romain Guy06882f82009-06-10 13:36:04 -07001038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1040 final IWindow client = win.mClient;
1041 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001042 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 final int N = localmWindows.size();
1045 final WindowState attached = win.mAttachedWindow;
1046 int i;
1047 if (attached == null) {
1048 int tokenWindowsPos = token.windows.size();
1049 if (token.appWindowToken != null) {
1050 int index = tokenWindowsPos-1;
1051 if (index >= 0) {
1052 // If this application has existing windows, we
1053 // simply place the new window on top of them... but
1054 // keep the starting window on top.
1055 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1056 // Base windows go behind everything else.
1057 placeWindowBefore(token.windows.get(0), win);
1058 tokenWindowsPos = 0;
1059 } else {
1060 AppWindowToken atoken = win.mAppToken;
1061 if (atoken != null &&
1062 token.windows.get(index) == atoken.startingWindow) {
1063 placeWindowBefore(token.windows.get(index), win);
1064 tokenWindowsPos--;
1065 } else {
1066 int newIdx = findIdxBasedOnAppTokens(win);
1067 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001068 //there is a window above this one associated with the same
1069 //apptoken note that the window could be a floating window
1070 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001072 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001073 TAG, "Adding window " + win + " at "
1074 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001076 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 }
1079 }
1080 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001081 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 TAG, "Figuring out where to add app window "
1083 + client.asBinder() + " (token=" + token + ")");
1084 // Figure out where the window should go, based on the
1085 // order of applications.
1086 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001087 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 for (i=NA-1; i>=0; i--) {
1089 AppWindowToken t = mAppTokens.get(i);
1090 if (t == token) {
1091 i--;
1092 break;
1093 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001094
Dianne Hackborna8f60182009-09-01 19:01:50 -07001095 // We haven't reached the token yet; if this token
1096 // is not going to the bottom and has windows, we can
1097 // use it as an anchor for when we do reach the token.
1098 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 pos = t.windows.get(0);
1100 }
1101 }
1102 // We now know the index into the apps. If we found
1103 // an app window above, that gives us the position; else
1104 // we need to look some more.
1105 if (pos != null) {
1106 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001107 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 if (atoken != null) {
1109 final int NC = atoken.windows.size();
1110 if (NC > 0) {
1111 WindowState bottom = atoken.windows.get(0);
1112 if (bottom.mSubLayer < 0) {
1113 pos = bottom;
1114 }
1115 }
1116 }
1117 placeWindowBefore(pos, win);
1118 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001119 // Continue looking down until we find the first
1120 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 while (i >= 0) {
1122 AppWindowToken t = mAppTokens.get(i);
1123 final int NW = t.windows.size();
1124 if (NW > 0) {
1125 pos = t.windows.get(NW-1);
1126 break;
1127 }
1128 i--;
1129 }
1130 if (pos != null) {
1131 // Move in front of any windows attached to this
1132 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001133 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 if (atoken != null) {
1135 final int NC = atoken.windows.size();
1136 if (NC > 0) {
1137 WindowState top = atoken.windows.get(NC-1);
1138 if (top.mSubLayer >= 0) {
1139 pos = top;
1140 }
1141 }
1142 }
1143 placeWindowAfter(pos, win);
1144 } else {
1145 // Just search for the start of this layer.
1146 final int myLayer = win.mBaseLayer;
1147 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001148 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 if (w.mBaseLayer > myLayer) {
1150 break;
1151 }
1152 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001153 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001154 TAG, "Adding window " + win + " at "
1155 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001157 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 }
1159 }
1160 }
1161 } else {
1162 // Figure out where window should go, based on layer.
1163 final int myLayer = win.mBaseLayer;
1164 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001165 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 i++;
1167 break;
1168 }
1169 }
1170 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001171 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001172 TAG, "Adding window " + win + " at "
1173 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001175 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 }
1177 if (addToToken) {
1178 token.windows.add(tokenWindowsPos, win);
1179 }
1180
1181 } else {
1182 // Figure out this window's ordering relative to the window
1183 // it is attached to.
1184 final int NA = token.windows.size();
1185 final int sublayer = win.mSubLayer;
1186 int largestSublayer = Integer.MIN_VALUE;
1187 WindowState windowWithLargestSublayer = null;
1188 for (i=0; i<NA; i++) {
1189 WindowState w = token.windows.get(i);
1190 final int wSublayer = w.mSubLayer;
1191 if (wSublayer >= largestSublayer) {
1192 largestSublayer = wSublayer;
1193 windowWithLargestSublayer = w;
1194 }
1195 if (sublayer < 0) {
1196 // For negative sublayers, we go below all windows
1197 // in the same sublayer.
1198 if (wSublayer >= sublayer) {
1199 if (addToToken) {
1200 token.windows.add(i, win);
1201 }
1202 placeWindowBefore(
1203 wSublayer >= 0 ? attached : w, win);
1204 break;
1205 }
1206 } else {
1207 // For positive sublayers, we go above all windows
1208 // in the same sublayer.
1209 if (wSublayer > sublayer) {
1210 if (addToToken) {
1211 token.windows.add(i, win);
1212 }
1213 placeWindowBefore(w, win);
1214 break;
1215 }
1216 }
1217 }
1218 if (i >= NA) {
1219 if (addToToken) {
1220 token.windows.add(win);
1221 }
1222 if (sublayer < 0) {
1223 placeWindowBefore(attached, win);
1224 } else {
1225 placeWindowAfter(largestSublayer >= 0
1226 ? windowWithLargestSublayer
1227 : attached,
1228 win);
1229 }
1230 }
1231 }
Romain Guy06882f82009-06-10 13:36:04 -07001232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 if (win.mAppToken != null && addToToken) {
1234 win.mAppToken.allAppWindows.add(win);
1235 }
1236 }
Romain Guy06882f82009-06-10 13:36:04 -07001237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238 static boolean canBeImeTarget(WindowState w) {
1239 final int fl = w.mAttrs.flags
1240 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1241 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1242 return w.isVisibleOrAdding();
1243 }
1244 return false;
1245 }
Romain Guy06882f82009-06-10 13:36:04 -07001246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001248 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 final int N = localmWindows.size();
1250 WindowState w = null;
1251 int i = N;
1252 while (i > 0) {
1253 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001254 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001255
Joe Onorato8a9b2202010-02-26 18:56:32 -08001256 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 // + Integer.toHexString(w.mAttrs.flags));
1258 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001259 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 // Yet more tricksyness! If this window is a "starting"
1262 // window, we do actually want to be on top of it, but
1263 // it is not -really- where input will go. So if the caller
1264 // is not actually looking to move the IME, look down below
1265 // for a real window to target...
1266 if (!willMove
1267 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1268 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001269 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1271 i--;
1272 w = wb;
1273 }
1274 }
1275 break;
1276 }
1277 }
Romain Guy06882f82009-06-10 13:36:04 -07001278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -07001280
Joe Onorato8a9b2202010-02-26 18:56:32 -08001281 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 if (willMove && w != null) {
1285 final WindowState curTarget = mInputMethodTarget;
1286 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 // Now some fun for dealing with window animations that
1289 // modify the Z order. We need to look at all windows below
1290 // the current target that are in this app, finding the highest
1291 // visible one in layering.
1292 AppWindowToken token = curTarget.mAppToken;
1293 WindowState highestTarget = null;
1294 int highestPos = 0;
1295 if (token.animating || token.animation != null) {
1296 int pos = 0;
1297 pos = localmWindows.indexOf(curTarget);
1298 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001299 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 if (win.mAppToken != token) {
1301 break;
1302 }
1303 if (!win.mRemoved) {
1304 if (highestTarget == null || win.mAnimLayer >
1305 highestTarget.mAnimLayer) {
1306 highestTarget = win;
1307 highestPos = pos;
1308 }
1309 }
1310 pos--;
1311 }
1312 }
Romain Guy06882f82009-06-10 13:36:04 -07001313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001315 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 + mNextAppTransition + " " + highestTarget
1317 + " animating=" + highestTarget.isAnimating()
1318 + " layer=" + highestTarget.mAnimLayer
1319 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001320
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001321 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 // If we are currently setting up for an animation,
1323 // hold everything until we can find out what will happen.
1324 mInputMethodTargetWaitingAnim = true;
1325 mInputMethodTarget = highestTarget;
1326 return highestPos + 1;
1327 } else if (highestTarget.isAnimating() &&
1328 highestTarget.mAnimLayer > w.mAnimLayer) {
1329 // If the window we are currently targeting is involved
1330 // with an animation, and it is on top of the next target
1331 // we will be over, then hold off on moving until
1332 // that is done.
1333 mInputMethodTarget = highestTarget;
1334 return highestPos + 1;
1335 }
1336 }
1337 }
1338 }
Romain Guy06882f82009-06-10 13:36:04 -07001339
Joe Onorato8a9b2202010-02-26 18:56:32 -08001340 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 if (w != null) {
1342 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001343 if (DEBUG_INPUT_METHOD) {
1344 RuntimeException e = null;
1345 if (!HIDE_STACK_CRAWLS) {
1346 e = new RuntimeException();
1347 e.fillInStackTrace();
1348 }
1349 Slog.w(TAG, "Moving IM target from "
1350 + mInputMethodTarget + " to " + w, e);
1351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 mInputMethodTarget = w;
1353 if (w.mAppToken != null) {
1354 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1355 } else {
1356 setInputMethodAnimLayerAdjustment(0);
1357 }
1358 }
1359 return i+1;
1360 }
1361 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001362 if (DEBUG_INPUT_METHOD) {
1363 RuntimeException e = null;
1364 if (!HIDE_STACK_CRAWLS) {
1365 e = new RuntimeException();
1366 e.fillInStackTrace();
1367 }
1368 Slog.w(TAG, "Moving IM target from "
1369 + mInputMethodTarget + " to null", e);
1370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371 mInputMethodTarget = null;
1372 setInputMethodAnimLayerAdjustment(0);
1373 }
1374 return -1;
1375 }
Romain Guy06882f82009-06-10 13:36:04 -07001376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 void addInputMethodWindowToListLocked(WindowState win) {
1378 int pos = findDesiredInputMethodWindowIndexLocked(true);
1379 if (pos >= 0) {
1380 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001381 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001382 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001384 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 moveInputMethodDialogsLocked(pos+1);
1386 return;
1387 }
1388 win.mTargetAppToken = null;
1389 addWindowToListInOrderLocked(win, true);
1390 moveInputMethodDialogsLocked(pos);
1391 }
Romain Guy06882f82009-06-10 13:36:04 -07001392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001394 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 mInputMethodAnimLayerAdjustment = adj;
1396 WindowState imw = mInputMethodWindow;
1397 if (imw != null) {
1398 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001399 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 + " anim layer: " + imw.mAnimLayer);
1401 int wi = imw.mChildWindows.size();
1402 while (wi > 0) {
1403 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001404 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001406 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 + " anim layer: " + cw.mAnimLayer);
1408 }
1409 }
1410 int di = mInputMethodDialogs.size();
1411 while (di > 0) {
1412 di --;
1413 imw = mInputMethodDialogs.get(di);
1414 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 + " anim layer: " + imw.mAnimLayer);
1417 }
1418 }
Romain Guy06882f82009-06-10 13:36:04 -07001419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1421 int wpos = mWindows.indexOf(win);
1422 if (wpos >= 0) {
1423 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001424 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001426 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 int NC = win.mChildWindows.size();
1428 while (NC > 0) {
1429 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001430 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 int cpos = mWindows.indexOf(cw);
1432 if (cpos >= 0) {
1433 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001434 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001435 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 mWindows.remove(cpos);
1437 }
1438 }
1439 }
1440 return interestingPos;
1441 }
Romain Guy06882f82009-06-10 13:36:04 -07001442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 private void reAddWindowToListInOrderLocked(WindowState win) {
1444 addWindowToListInOrderLocked(win, false);
1445 // This is a hack to get all of the child windows added as well
1446 // at the right position. Child windows should be rare and
1447 // this case should be rare, so it shouldn't be that big a deal.
1448 int wpos = mWindows.indexOf(win);
1449 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001451 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001453 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 reAddWindowLocked(wpos, win);
1455 }
1456 }
Romain Guy06882f82009-06-10 13:36:04 -07001457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 void logWindowList(String prefix) {
1459 int N = mWindows.size();
1460 while (N > 0) {
1461 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001462 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 }
1464 }
Romain Guy06882f82009-06-10 13:36:04 -07001465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 void moveInputMethodDialogsLocked(int pos) {
1467 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001470 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 for (int i=0; i<N; i++) {
1472 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1473 }
1474 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 logWindowList(" ");
1477 }
Romain Guy06882f82009-06-10 13:36:04 -07001478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 if (pos >= 0) {
1480 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1481 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001482 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 if (wp == mInputMethodWindow) {
1484 pos++;
1485 }
1486 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001487 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 for (int i=0; i<N; i++) {
1489 WindowState win = dialogs.get(i);
1490 win.mTargetAppToken = targetAppToken;
1491 pos = reAddWindowLocked(pos, win);
1492 }
1493 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001494 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 logWindowList(" ");
1496 }
1497 return;
1498 }
1499 for (int i=0; i<N; i++) {
1500 WindowState win = dialogs.get(i);
1501 win.mTargetAppToken = null;
1502 reAddWindowToListInOrderLocked(win);
1503 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001504 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 logWindowList(" ");
1506 }
1507 }
1508 }
Romain Guy06882f82009-06-10 13:36:04 -07001509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1511 final WindowState imWin = mInputMethodWindow;
1512 final int DN = mInputMethodDialogs.size();
1513 if (imWin == null && DN == 0) {
1514 return false;
1515 }
Romain Guy06882f82009-06-10 13:36:04 -07001516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1518 if (imPos >= 0) {
1519 // In this case, the input method windows are to be placed
1520 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 // First check to see if the input method windows are already
1523 // located here, and contiguous.
1524 final int N = mWindows.size();
1525 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001526 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 // Figure out the actual input method window that should be
1529 // at the bottom of their stack.
1530 WindowState baseImWin = imWin != null
1531 ? imWin : mInputMethodDialogs.get(0);
1532 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001533 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (cw.mSubLayer < 0) baseImWin = cw;
1535 }
Romain Guy06882f82009-06-10 13:36:04 -07001536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 if (firstImWin == baseImWin) {
1538 // The windows haven't moved... but are they still contiguous?
1539 // First find the top IM window.
1540 int pos = imPos+1;
1541 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001542 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 break;
1544 }
1545 pos++;
1546 }
1547 pos++;
1548 // Now there should be no more input method windows above.
1549 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001550 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 break;
1552 }
1553 pos++;
1554 }
1555 if (pos >= N) {
1556 // All is good!
1557 return false;
1558 }
1559 }
Romain Guy06882f82009-06-10 13:36:04 -07001560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 if (imWin != null) {
1562 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001563 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 logWindowList(" ");
1565 }
1566 imPos = tmpRemoveWindowLocked(imPos, imWin);
1567 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001568 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 logWindowList(" ");
1570 }
1571 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1572 reAddWindowLocked(imPos, imWin);
1573 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001574 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 logWindowList(" ");
1576 }
1577 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1578 } else {
1579 moveInputMethodDialogsLocked(imPos);
1580 }
Romain Guy06882f82009-06-10 13:36:04 -07001581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 } else {
1583 // In this case, the input method windows go in a fixed layer,
1584 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001587 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 tmpRemoveWindowLocked(0, imWin);
1589 imWin.mTargetAppToken = null;
1590 reAddWindowToListInOrderLocked(imWin);
1591 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001592 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 logWindowList(" ");
1594 }
1595 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1596 } else {
1597 moveInputMethodDialogsLocked(-1);;
1598 }
Romain Guy06882f82009-06-10 13:36:04 -07001599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 }
Romain Guy06882f82009-06-10 13:36:04 -07001601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 if (needAssignLayers) {
1603 assignLayersLocked();
1604 }
Romain Guy06882f82009-06-10 13:36:04 -07001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 return true;
1607 }
Romain Guy06882f82009-06-10 13:36:04 -07001608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 void adjustInputMethodDialogsLocked() {
1610 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1611 }
Romain Guy06882f82009-06-10 13:36:04 -07001612
Dianne Hackborn25994b42009-09-04 14:21:19 -07001613 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001614 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001615 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1616 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1617 ? wallpaperTarget.mAppToken.animation : null)
1618 + " upper=" + mUpperWallpaperTarget
1619 + " lower=" + mLowerWallpaperTarget);
1620 return (wallpaperTarget != null
1621 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1622 && wallpaperTarget.mAppToken.animation != null)))
1623 || mUpperWallpaperTarget != null
1624 || mLowerWallpaperTarget != null;
1625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001626
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001627 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1628 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001629
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001630 int adjustWallpaperWindowsLocked() {
1631 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001632
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001633 final int dw = mDisplay.getWidth();
1634 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001635
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001636 // First find top-most window that has asked to be on top of the
1637 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001638 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001639 int N = localmWindows.size();
1640 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001641 WindowState foundW = null;
1642 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001643 WindowState topCurW = null;
1644 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001645 int i = N;
1646 while (i > 0) {
1647 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001648 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001649 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1650 if (topCurW == null) {
1651 topCurW = w;
1652 topCurI = i;
1653 }
1654 continue;
1655 }
1656 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001657 if (w.mAppToken != null) {
1658 // If this window's app token is hidden and not animating,
1659 // it is of no interest to us.
1660 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001661 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001662 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001663 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001664 continue;
1665 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001666 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001667 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001668 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1669 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001670 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001671 && (mWallpaperTarget == w
1672 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001673 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001674 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001675 foundW = w;
1676 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001677 if (w == mWallpaperTarget && ((w.mAppToken != null
1678 && w.mAppToken.animation != null)
1679 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001680 // The current wallpaper target is animating, so we'll
1681 // look behind it for another possible target and figure
1682 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001683 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001684 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001685 continue;
1686 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001687 break;
1688 }
1689 }
1690
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001691 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001692 // If we are currently waiting for an app transition, and either
1693 // the current target or the next target are involved with it,
1694 // then hold off on doing anything with the wallpaper.
1695 // Note that we are checking here for just whether the target
1696 // is part of an app token... which is potentially overly aggressive
1697 // (the app token may not be involved in the transition), but good
1698 // enough (we'll just wait until whatever transition is pending
1699 // executes).
1700 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001701 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001702 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001703 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001704 }
1705 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001706 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001707 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001708 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001709 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001710 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001711
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001712 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001713 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001714 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001715 + " oldTarget: " + mWallpaperTarget);
1716 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001717
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001718 mLowerWallpaperTarget = null;
1719 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001720
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001721 WindowState oldW = mWallpaperTarget;
1722 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001723
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001724 // Now what is happening... if the current and new targets are
1725 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001726 if (foundW != null && oldW != null) {
1727 boolean oldAnim = oldW.mAnimation != null
1728 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1729 boolean foundAnim = foundW.mAnimation != null
1730 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001731 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001732 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001733 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001734 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001735 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001736 int oldI = localmWindows.indexOf(oldW);
1737 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001738 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001739 }
1740 if (oldI >= 0) {
1741 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001742 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001743 + "=" + oldW + "; new#" + foundI
1744 + "=" + foundW);
1745 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001746
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001747 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001748 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001749 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001750 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001751 }
1752 mWallpaperTarget = oldW;
1753 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001754
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001755 // Now set the upper and lower wallpaper targets
1756 // correctly, and make sure that we are positioning
1757 // the wallpaper below the lower.
1758 if (foundI > oldI) {
1759 // The new target is on top of the old one.
1760 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001761 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001762 }
1763 mUpperWallpaperTarget = foundW;
1764 mLowerWallpaperTarget = oldW;
1765 foundW = oldW;
1766 foundI = oldI;
1767 } else {
1768 // The new target is below the old one.
1769 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001770 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001771 }
1772 mUpperWallpaperTarget = oldW;
1773 mLowerWallpaperTarget = foundW;
1774 }
1775 }
1776 }
1777 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001778
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001779 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001780 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001781 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1782 || (mLowerWallpaperTarget.mAppToken != null
1783 && mLowerWallpaperTarget.mAppToken.animation != null);
1784 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1785 || (mUpperWallpaperTarget.mAppToken != null
1786 && mUpperWallpaperTarget.mAppToken.animation != null);
1787 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001788 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001789 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001790 }
1791 mLowerWallpaperTarget = null;
1792 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001793 }
1794 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001795
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001796 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001797 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001798 // The window is visible to the compositor... but is it visible
1799 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001800 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001801 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001802
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001803 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001804 // its layer adjustment. Only do this if we are not transfering
1805 // between two wallpaper targets.
1806 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001807 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001808 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001809
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001810 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1811 * TYPE_LAYER_MULTIPLIER
1812 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001813
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001814 // Now w is the window we are supposed to be behind... but we
1815 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001816 // AND any starting window associated with it, AND below the
1817 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001818 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001819 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001820 if (wb.mBaseLayer < maxLayer &&
1821 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001822 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001823 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001824 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001825 // This window is not related to the previous one in any
1826 // interesting way, so stop here.
1827 break;
1828 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001829 foundW = wb;
1830 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001831 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001832 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001833 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001834 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001835
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001836 if (foundW == null && topCurW != null) {
1837 // There is no wallpaper target, so it goes at the bottom.
1838 // We will assume it is the same place as last time, if known.
1839 foundW = topCurW;
1840 foundI = topCurI+1;
1841 } else {
1842 // Okay i is the position immediately above the wallpaper. Look at
1843 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001844 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001846
Dianne Hackborn284ac932009-08-28 10:34:25 -07001847 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001848 if (mWallpaperTarget.mWallpaperX >= 0) {
1849 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001850 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001851 }
1852 if (mWallpaperTarget.mWallpaperY >= 0) {
1853 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001854 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001855 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001856 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001857
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001858 // Start stepping backwards from here, ensuring that our wallpaper windows
1859 // are correctly placed.
1860 int curTokenIndex = mWallpaperTokens.size();
1861 while (curTokenIndex > 0) {
1862 curTokenIndex--;
1863 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001864 if (token.hidden == visible) {
1865 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1866 token.hidden = !visible;
1867 // Need to do a layout to ensure the wallpaper now has the
1868 // correct size.
1869 mLayoutNeeded = true;
1870 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001871
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001872 int curWallpaperIndex = token.windows.size();
1873 while (curWallpaperIndex > 0) {
1874 curWallpaperIndex--;
1875 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001876
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001877 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001878 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001879 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001880
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001881 // First, make sure the client has the current visibility
1882 // state.
1883 if (wallpaper.mWallpaperVisible != visible) {
1884 wallpaper.mWallpaperVisible = visible;
1885 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001886 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001887 "Setting visibility of wallpaper " + wallpaper
1888 + ": " + visible);
1889 wallpaper.mClient.dispatchAppVisibility(visible);
1890 } catch (RemoteException e) {
1891 }
1892 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001893
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001894 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001895 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001896 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001897
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001898 // First, if this window is at the current index, then all
1899 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001900 if (wallpaper == foundW) {
1901 foundI--;
1902 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001903 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001904 continue;
1905 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001906
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001907 // The window didn't match... the current wallpaper window,
1908 // wherever it is, is in the wrong place, so make sure it is
1909 // not in the list.
1910 int oldIndex = localmWindows.indexOf(wallpaper);
1911 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001912 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001913 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001914 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001915 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001916 if (oldIndex < foundI) {
1917 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001918 }
1919 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001920
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001921 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001923 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001924 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001925
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001926 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001927 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001928 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001929 }
1930 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001931
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001932 return changed;
1933 }
1934
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001935 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001936 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001937 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001938 mWallpaperAnimLayerAdjustment = adj;
1939 int curTokenIndex = mWallpaperTokens.size();
1940 while (curTokenIndex > 0) {
1941 curTokenIndex--;
1942 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1943 int curWallpaperIndex = token.windows.size();
1944 while (curWallpaperIndex > 0) {
1945 curWallpaperIndex--;
1946 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1947 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001948 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001949 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001950 }
1951 }
1952 }
1953
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001954 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1955 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001956 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001957 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001958 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001959 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001960 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1961 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1962 changed = wallpaperWin.mXOffset != offset;
1963 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001964 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001965 + wallpaperWin + " x: " + offset);
1966 wallpaperWin.mXOffset = offset;
1967 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001968 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001969 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001970 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001971 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001972 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001973
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001974 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001975 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001976 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1977 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1978 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001979 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001980 + wallpaperWin + " y: " + offset);
1981 changed = true;
1982 wallpaperWin.mYOffset = offset;
1983 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001984 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001985 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001986 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001987 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001988 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001989
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001990 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001991 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001992 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001993 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1994 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001995 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001996 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001997 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001998 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001999 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2000 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002001 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002002 if (mWaitingOnWallpaper != null) {
2003 long start = SystemClock.uptimeMillis();
2004 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2005 < start) {
2006 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002007 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002008 "Waiting for offset complete...");
2009 mWindowMap.wait(WALLPAPER_TIMEOUT);
2010 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002011 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002013 if ((start+WALLPAPER_TIMEOUT)
2014 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002015 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002016 + wallpaperWin);
2017 mLastWallpaperTimeoutTime = start;
2018 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002019 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002020 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002021 }
2022 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002023 } catch (RemoteException e) {
2024 }
2025 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002026
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002027 return changed;
2028 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002029
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002030 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002031 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002032 if (mWaitingOnWallpaper != null &&
2033 mWaitingOnWallpaper.mClient.asBinder() == window) {
2034 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002035 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002036 }
2037 }
2038 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002039
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002040 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002041 final int dw = mDisplay.getWidth();
2042 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002043
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002044 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002045
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002046 WindowState target = mWallpaperTarget;
2047 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002048 if (target.mWallpaperX >= 0) {
2049 mLastWallpaperX = target.mWallpaperX;
2050 } else if (changingTarget.mWallpaperX >= 0) {
2051 mLastWallpaperX = changingTarget.mWallpaperX;
2052 }
2053 if (target.mWallpaperY >= 0) {
2054 mLastWallpaperY = target.mWallpaperY;
2055 } else if (changingTarget.mWallpaperY >= 0) {
2056 mLastWallpaperY = changingTarget.mWallpaperY;
2057 }
2058 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002059
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002060 int curTokenIndex = mWallpaperTokens.size();
2061 while (curTokenIndex > 0) {
2062 curTokenIndex--;
2063 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2064 int curWallpaperIndex = token.windows.size();
2065 while (curWallpaperIndex > 0) {
2066 curWallpaperIndex--;
2067 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2068 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2069 wallpaper.computeShownFrameLocked();
2070 changed = true;
2071 // We only want to be synchronous with one wallpaper.
2072 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002073 }
2074 }
2075 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002076
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002077 return changed;
2078 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002079
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002080 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002081 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002082 final int dw = mDisplay.getWidth();
2083 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002084
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002085 int curTokenIndex = mWallpaperTokens.size();
2086 while (curTokenIndex > 0) {
2087 curTokenIndex--;
2088 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002089 if (token.hidden == visible) {
2090 token.hidden = !visible;
2091 // Need to do a layout to ensure the wallpaper now has the
2092 // correct size.
2093 mLayoutNeeded = true;
2094 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002095
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002096 int curWallpaperIndex = token.windows.size();
2097 while (curWallpaperIndex > 0) {
2098 curWallpaperIndex--;
2099 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2100 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002101 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002102 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002103
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002104 if (wallpaper.mWallpaperVisible != visible) {
2105 wallpaper.mWallpaperVisible = visible;
2106 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002107 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002108 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002109 + ": " + visible);
2110 wallpaper.mClient.dispatchAppVisibility(visible);
2111 } catch (RemoteException e) {
2112 }
2113 }
2114 }
2115 }
2116 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 public int addWindow(Session session, IWindow client,
2119 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002120 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002121 int res = mPolicy.checkAddPermission(attrs);
2122 if (res != WindowManagerImpl.ADD_OKAY) {
2123 return res;
2124 }
Romain Guy06882f82009-06-10 13:36:04 -07002125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 boolean reportNewConfig = false;
2127 WindowState attachedWindow = null;
2128 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002129 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002133 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002134 }
Romain Guy06882f82009-06-10 13:36:04 -07002135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002137 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2139 }
2140
2141 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002142 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002144 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 + attrs.token + ". Aborting.");
2146 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2147 }
2148 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2149 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002150 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 + attrs.token + ". Aborting.");
2152 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2153 }
2154 }
2155
2156 boolean addToken = false;
2157 WindowToken token = mTokenMap.get(attrs.token);
2158 if (token == null) {
2159 if (attrs.type >= FIRST_APPLICATION_WINDOW
2160 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002161 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 + attrs.token + ". Aborting.");
2163 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2164 }
2165 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002166 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 + attrs.token + ". Aborting.");
2168 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2169 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002170 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002171 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002172 + attrs.token + ". Aborting.");
2173 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002175 token = new WindowToken(attrs.token, -1, false);
2176 addToken = true;
2177 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2178 && attrs.type <= LAST_APPLICATION_WINDOW) {
2179 AppWindowToken atoken = token.appWindowToken;
2180 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002181 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 + token + ". Aborting.");
2183 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2184 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002185 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 + token + ". Aborting.");
2187 return WindowManagerImpl.ADD_APP_EXITING;
2188 }
2189 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2190 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002191 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2193 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2194 }
2195 } else if (attrs.type == TYPE_INPUT_METHOD) {
2196 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002197 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 + attrs.token + ". Aborting.");
2199 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2200 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002201 } else if (attrs.type == TYPE_WALLPAPER) {
2202 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002203 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002204 + attrs.token + ". Aborting.");
2205 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207 }
2208
2209 win = new WindowState(session, client, token,
2210 attachedWindow, attrs, viewVisibility);
2211 if (win.mDeathRecipient == null) {
2212 // Client has apparently died, so there is no reason to
2213 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002214 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 + " that is dead, aborting.");
2216 return WindowManagerImpl.ADD_APP_EXITING;
2217 }
2218
2219 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 res = mPolicy.prepareAddWindowLw(win, attrs);
2222 if (res != WindowManagerImpl.ADD_OKAY) {
2223 return res;
2224 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002225
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002226 if (outInputChannel != null) {
2227 String name = win.makeInputChannelName();
2228 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2229 win.mInputChannel = inputChannels[0];
2230 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2231
2232 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234
2235 // From now on, no exceptions or errors allowed!
2236
2237 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002238
Dianne Hackborn5132b372010-07-29 12:51:35 -07002239 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 if (addToken) {
2242 mTokenMap.put(attrs.token, token);
2243 mTokenList.add(token);
2244 }
2245 win.attach();
2246 mWindowMap.put(client.asBinder(), win);
2247
2248 if (attrs.type == TYPE_APPLICATION_STARTING &&
2249 token.appWindowToken != null) {
2250 token.appWindowToken.startingWindow = win;
2251 }
2252
2253 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 if (attrs.type == TYPE_INPUT_METHOD) {
2256 mInputMethodWindow = win;
2257 addInputMethodWindowToListLocked(win);
2258 imMayMove = false;
2259 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2260 mInputMethodDialogs.add(win);
2261 addWindowToListInOrderLocked(win, true);
2262 adjustInputMethodDialogsLocked();
2263 imMayMove = false;
2264 } else {
2265 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002266 if (attrs.type == TYPE_WALLPAPER) {
2267 mLastWallpaperTimeoutTime = 0;
2268 adjustWallpaperWindowsLocked();
2269 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002270 adjustWallpaperWindowsLocked();
2271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 }
Romain Guy06882f82009-06-10 13:36:04 -07002273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 if (mInTouchMode) {
2279 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2280 }
2281 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2282 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2283 }
Romain Guy06882f82009-06-10 13:36:04 -07002284
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002285 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002287 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2288 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 imMayMove = false;
2290 }
2291 }
Romain Guy06882f82009-06-10 13:36:04 -07002292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002294 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 }
Romain Guy06882f82009-06-10 13:36:04 -07002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 assignLayersLocked();
2298 // Don't do layout here, the window must call
2299 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 //dump();
2302
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002303 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002304 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002305 }
Jeff Brown349703e2010-06-22 01:27:15 -07002306
Joe Onorato8a9b2202010-02-26 18:56:32 -08002307 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308 TAG, "New client " + client.asBinder()
2309 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002310
2311 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2312 reportNewConfig = true;
2313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314 }
2315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 if (reportNewConfig) {
2317 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return res;
2323 }
Romain Guy06882f82009-06-10 13:36:04 -07002324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 public void removeWindow(Session session, IWindow client) {
2326 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002327 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 if (win == null) {
2329 return;
2330 }
2331 removeWindowLocked(session, win);
2332 }
2333 }
Romain Guy06882f82009-06-10 13:36:04 -07002334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 public void removeWindowLocked(Session session, WindowState win) {
2336
Joe Onorato8a9b2202010-02-26 18:56:32 -08002337 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 TAG, "Remove " + win + " client="
2339 + Integer.toHexString(System.identityHashCode(
2340 win.mClient.asBinder()))
2341 + ", surface=" + win.mSurface);
2342
2343 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002344
2345 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002346
Joe Onorato8a9b2202010-02-26 18:56:32 -08002347 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2349 + " mExiting=" + win.mExiting
2350 + " isAnimating=" + win.isAnimating()
2351 + " app-animation="
2352 + (win.mAppToken != null ? win.mAppToken.animation : null)
2353 + " inPendingTransaction="
2354 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2355 + " mDisplayFrozen=" + mDisplayFrozen);
2356 // Visibility of the removed window. Will be used later to update orientation later on.
2357 boolean wasVisible = false;
2358 // First, see if we need to run an animation. If we do, we have
2359 // to hold off on removing the window until the animation is done.
2360 // If the display is frozen, just remove immediately, since the
2361 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002362 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 // If we are not currently running the exit animation, we
2364 // need to see about starting one.
2365 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2368 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2369 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2370 }
2371 // Try starting an animation.
2372 if (applyAnimationLocked(win, transit, false)) {
2373 win.mExiting = true;
2374 }
2375 }
2376 if (win.mExiting || win.isAnimating()) {
2377 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002378 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 win.mExiting = true;
2380 win.mRemoveOnExit = true;
2381 mLayoutNeeded = true;
2382 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2383 performLayoutAndPlaceSurfacesLocked();
2384 if (win.mAppToken != null) {
2385 win.mAppToken.updateReportedVisibilityLocked();
2386 }
2387 //dump();
2388 Binder.restoreCallingIdentity(origId);
2389 return;
2390 }
2391 }
2392
2393 removeWindowInnerLocked(session, win);
2394 // Removing a visible window will effect the computed orientation
2395 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002396 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002397 != mForcedAppOrientation
2398 && updateOrientationFromAppTokensLocked()) {
2399 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 }
2401 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2402 Binder.restoreCallingIdentity(origId);
2403 }
Romain Guy06882f82009-06-10 13:36:04 -07002404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 if (mInputMethodTarget == win) {
2409 moveInputMethodWindowsIfNeededLocked(false);
2410 }
Romain Guy06882f82009-06-10 13:36:04 -07002411
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002412 if (false) {
2413 RuntimeException e = new RuntimeException("here");
2414 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002415 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002416 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 mPolicy.removeWindowLw(win);
2419 win.removeLocked();
2420
2421 mWindowMap.remove(win.mClient.asBinder());
2422 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002423 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002424 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425
2426 if (mInputMethodWindow == win) {
2427 mInputMethodWindow = null;
2428 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2429 mInputMethodDialogs.remove(win);
2430 }
Romain Guy06882f82009-06-10 13:36:04 -07002431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002432 final WindowToken token = win.mToken;
2433 final AppWindowToken atoken = win.mAppToken;
2434 token.windows.remove(win);
2435 if (atoken != null) {
2436 atoken.allAppWindows.remove(win);
2437 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002438 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 TAG, "**** Removing window " + win + ": count="
2440 + token.windows.size());
2441 if (token.windows.size() == 0) {
2442 if (!token.explicit) {
2443 mTokenMap.remove(token.token);
2444 mTokenList.remove(token);
2445 } else if (atoken != null) {
2446 atoken.firstWindowDrawn = false;
2447 }
2448 }
2449
2450 if (atoken != null) {
2451 if (atoken.startingWindow == win) {
2452 atoken.startingWindow = null;
2453 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2454 // If this is the last window and we had requested a starting
2455 // transition window, well there is no point now.
2456 atoken.startingData = null;
2457 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2458 // If this is the last window except for a starting transition
2459 // window, we need to get rid of the starting transition.
2460 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002461 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 + ": no more real windows");
2463 }
2464 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2465 mH.sendMessage(m);
2466 }
2467 }
Romain Guy06882f82009-06-10 13:36:04 -07002468
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002469 if (win.mAttrs.type == TYPE_WALLPAPER) {
2470 mLastWallpaperTimeoutTime = 0;
2471 adjustWallpaperWindowsLocked();
2472 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002473 adjustWallpaperWindowsLocked();
2474 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 if (!mInLayout) {
2477 assignLayersLocked();
2478 mLayoutNeeded = true;
2479 performLayoutAndPlaceSurfacesLocked();
2480 if (win.mAppToken != null) {
2481 win.mAppToken.updateReportedVisibilityLocked();
2482 }
2483 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002484
2485 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 }
2487
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002488 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2489 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2490 + ": " + msg + " / " + w.mAttrs.getTitle();
2491 if (where != null) {
2492 Slog.i(TAG, str, where);
2493 } else {
2494 Slog.i(TAG, str);
2495 }
2496 }
2497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
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) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002504 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002505 Surface.openTransaction();
2506 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002507 if (SHOW_TRANSACTIONS) logSurface(w,
2508 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 w.mSurface.setTransparentRegionHint(region);
2510 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002511 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002512 Surface.closeTransaction();
2513 }
2514 }
2515 }
2516 } finally {
2517 Binder.restoreCallingIdentity(origId);
2518 }
2519 }
2520
2521 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002522 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 Rect visibleInsets) {
2524 long origId = Binder.clearCallingIdentity();
2525 try {
2526 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002527 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528 if (w != null) {
2529 w.mGivenInsetsPending = false;
2530 w.mGivenContentInsets.set(contentInsets);
2531 w.mGivenVisibleInsets.set(visibleInsets);
2532 w.mTouchableInsets = touchableInsets;
2533 mLayoutNeeded = true;
2534 performLayoutAndPlaceSurfacesLocked();
2535 }
2536 }
2537 } finally {
2538 Binder.restoreCallingIdentity(origId);
2539 }
2540 }
Romain Guy06882f82009-06-10 13:36:04 -07002541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 public void getWindowDisplayFrame(Session session, IWindow client,
2543 Rect outDisplayFrame) {
2544 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002545 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 if (win == null) {
2547 outDisplayFrame.setEmpty();
2548 return;
2549 }
2550 outDisplayFrame.set(win.mDisplayFrame);
2551 }
2552 }
2553
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002554 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2555 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002556 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2557 window.mWallpaperX = x;
2558 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002559 window.mWallpaperXStep = xStep;
2560 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002561 if (updateWallpaperOffsetLocked(window, true)) {
2562 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002563 }
2564 }
2565 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002566
Dianne Hackborn75804932009-10-20 20:15:20 -07002567 void wallpaperCommandComplete(IBinder window, Bundle result) {
2568 synchronized (mWindowMap) {
2569 if (mWaitingOnWallpaper != null &&
2570 mWaitingOnWallpaper.mClient.asBinder() == window) {
2571 mWaitingOnWallpaper = null;
2572 mWindowMap.notifyAll();
2573 }
2574 }
2575 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002576
Dianne Hackborn75804932009-10-20 20:15:20 -07002577 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2578 String action, int x, int y, int z, Bundle extras, boolean sync) {
2579 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2580 || window == mUpperWallpaperTarget) {
2581 boolean doWait = sync;
2582 int curTokenIndex = mWallpaperTokens.size();
2583 while (curTokenIndex > 0) {
2584 curTokenIndex--;
2585 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2586 int curWallpaperIndex = token.windows.size();
2587 while (curWallpaperIndex > 0) {
2588 curWallpaperIndex--;
2589 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2590 try {
2591 wallpaper.mClient.dispatchWallpaperCommand(action,
2592 x, y, z, extras, sync);
2593 // We only want to be synchronous with one wallpaper.
2594 sync = false;
2595 } catch (RemoteException e) {
2596 }
2597 }
2598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002599
Dianne Hackborn75804932009-10-20 20:15:20 -07002600 if (doWait) {
2601 // XXX Need to wait for result.
2602 }
2603 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002604
Dianne Hackborn75804932009-10-20 20:15:20 -07002605 return null;
2606 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 public int relayoutWindow(Session session, IWindow client,
2609 WindowManager.LayoutParams attrs, int requestedWidth,
2610 int requestedHeight, int viewVisibility, boolean insetsPending,
2611 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002612 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 boolean displayed = false;
2614 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002615 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002619 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 if (win == null) {
2621 return 0;
2622 }
2623 win.mRequestedWidth = requestedWidth;
2624 win.mRequestedHeight = requestedHeight;
2625
2626 if (attrs != null) {
2627 mPolicy.adjustWindowParamsLw(attrs);
2628 }
Romain Guy06882f82009-06-10 13:36:04 -07002629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 int attrChanges = 0;
2631 int flagChanges = 0;
2632 if (attrs != null) {
2633 flagChanges = win.mAttrs.flags ^= attrs.flags;
2634 attrChanges = win.mAttrs.copyFrom(attrs);
2635 }
2636
Joe Onorato8a9b2202010-02-26 18:56:32 -08002637 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638
2639 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2640 win.mAlpha = attrs.alpha;
2641 }
2642
2643 final boolean scaledWindow =
2644 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2645
2646 if (scaledWindow) {
2647 // requested{Width|Height} Surface's physical size
2648 // attrs.{width|height} Size on screen
2649 win.mHScale = (attrs.width != requestedWidth) ?
2650 (attrs.width / (float)requestedWidth) : 1.0f;
2651 win.mVScale = (attrs.height != requestedHeight) ?
2652 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002653 } else {
2654 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655 }
2656
2657 boolean imMayMove = (flagChanges&(
2658 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2659 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 boolean focusMayChange = win.mViewVisibility != viewVisibility
2662 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2663 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002664
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002665 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2666 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 win.mRelayoutCalled = true;
2669 final int oldVisibility = win.mViewVisibility;
2670 win.mViewVisibility = viewVisibility;
2671 if (viewVisibility == View.VISIBLE &&
2672 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2673 displayed = !win.isVisibleLw();
2674 if (win.mExiting) {
2675 win.mExiting = false;
2676 win.mAnimation = null;
2677 }
2678 if (win.mDestroying) {
2679 win.mDestroying = false;
2680 mDestroySurface.remove(win);
2681 }
2682 if (oldVisibility == View.GONE) {
2683 win.mEnterAnimationPending = true;
2684 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002685 if (displayed) {
2686 if (win.mSurface != null && !win.mDrawPending
2687 && !win.mCommitDrawPending && !mDisplayFrozen
2688 && mPolicy.isScreenOn()) {
2689 applyEnterAnimationLocked(win);
2690 }
2691 if ((win.mAttrs.flags
2692 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2693 if (DEBUG_VISIBILITY) Slog.v(TAG,
2694 "Relayout window turning screen on: " + win);
2695 win.mTurnOnScreen = true;
2696 }
2697 int diff = 0;
2698 if (win.mConfiguration != mCurConfiguration
2699 && (win.mConfiguration == null
2700 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2701 win.mConfiguration = mCurConfiguration;
2702 if (DEBUG_CONFIGURATION) {
2703 Slog.i(TAG, "Window " + win + " visible with new config: "
2704 + win.mConfiguration + " / 0x"
2705 + Integer.toHexString(diff));
2706 }
2707 outConfig.setTo(mCurConfiguration);
2708 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2711 // To change the format, we need to re-build the surface.
2712 win.destroySurfaceLocked();
2713 displayed = true;
2714 }
2715 try {
2716 Surface surface = win.createSurfaceLocked();
2717 if (surface != null) {
2718 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002719 win.mReportDestroySurface = false;
2720 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002721 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002722 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002724 // For some reason there isn't a surface. Clear the
2725 // caller's object so they see the same state.
2726 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 }
2728 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002729 mInputMonitor.updateInputWindowsLw();
2730
Joe Onorato8a9b2202010-02-26 18:56:32 -08002731 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002732 + client + " (" + win.mAttrs.getTitle() + ")",
2733 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 Binder.restoreCallingIdentity(origId);
2735 return 0;
2736 }
2737 if (displayed) {
2738 focusMayChange = true;
2739 }
2740 if (win.mAttrs.type == TYPE_INPUT_METHOD
2741 && mInputMethodWindow == null) {
2742 mInputMethodWindow = win;
2743 imMayMove = true;
2744 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002745 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2746 && win.mAppToken != null
2747 && win.mAppToken.startingWindow != null) {
2748 // Special handling of starting window over the base
2749 // window of the app: propagate lock screen flags to it,
2750 // to provide the correct semantics while starting.
2751 final int mask =
2752 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002753 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2754 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002755 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2756 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 } else {
2759 win.mEnterAnimationPending = false;
2760 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002761 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002762 + ": mExiting=" + win.mExiting
2763 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 // If we are not currently running the exit animation, we
2765 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002766 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 // Try starting an animation; if there isn't one, we
2768 // can destroy the surface right away.
2769 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2770 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2771 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2772 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002773 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002775 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 } else if (win.isAnimating()) {
2778 // Currently in a hide animation... turn this into
2779 // an exit.
2780 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002781 } else if (win == mWallpaperTarget) {
2782 // If the wallpaper is currently behind this
2783 // window, we need to change both of them inside
2784 // of a transaction to avoid artifacts.
2785 win.mExiting = true;
2786 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002787 } else {
2788 if (mInputMethodWindow == win) {
2789 mInputMethodWindow = null;
2790 }
2791 win.destroySurfaceLocked();
2792 }
2793 }
2794 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002795
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002796 if (win.mSurface == null || (win.getAttrs().flags
2797 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2798 || win.mSurfacePendingDestroy) {
2799 // We are being called from a local process, which
2800 // means outSurface holds its current surface. Ensure the
2801 // surface object is cleared, but we don't want it actually
2802 // destroyed at this point.
2803 win.mSurfacePendingDestroy = false;
2804 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002805 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002806 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002807 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002808 "Keeping surface, will report destroy: " + win);
2809 win.mReportDestroySurface = true;
2810 outSurface.copyFrom(win.mSurface);
2811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812 }
2813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 if (focusMayChange) {
2815 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2816 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 imMayMove = false;
2818 }
2819 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2820 }
Romain Guy06882f82009-06-10 13:36:04 -07002821
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002822 // updateFocusedWindowLocked() already assigned layers so we only need to
2823 // reassign them at this point if the IM window state gets shuffled
2824 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002827 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2828 // Little hack here -- we -should- be able to rely on the
2829 // function to return true if the IME has moved and needs
2830 // its layer recomputed. However, if the IME was hidden
2831 // and isn't actually moved in the list, its layer may be
2832 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 assignLayers = true;
2834 }
2835 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002836 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002837 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002838 assignLayers = true;
2839 }
2840 }
Romain Guy06882f82009-06-10 13:36:04 -07002841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002842 mLayoutNeeded = true;
2843 win.mGivenInsetsPending = insetsPending;
2844 if (assignLayers) {
2845 assignLayersLocked();
2846 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002847 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002849 if (displayed && win.mIsWallpaper) {
2850 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002851 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 if (win.mAppToken != null) {
2854 win.mAppToken.updateReportedVisibilityLocked();
2855 }
2856 outFrame.set(win.mFrame);
2857 outContentInsets.set(win.mContentInsets);
2858 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002859 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002861 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 + ", requestedHeight=" + requestedHeight
2863 + ", viewVisibility=" + viewVisibility
2864 + "\nRelayout returning frame=" + outFrame
2865 + ", surface=" + outSurface);
2866
Joe Onorato8a9b2202010-02-26 18:56:32 -08002867 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2869
2870 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002871
2872 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 }
2874
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002875 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 sendNewConfiguration();
2877 }
Romain Guy06882f82009-06-10 13:36:04 -07002878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2882 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2883 }
2884
2885 public void finishDrawingWindow(Session session, IWindow client) {
2886 final long origId = Binder.clearCallingIdentity();
2887 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002888 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002890 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2891 adjustWallpaperWindowsLocked();
2892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 mLayoutNeeded = true;
2894 performLayoutAndPlaceSurfacesLocked();
2895 }
2896 }
2897 Binder.restoreCallingIdentity(origId);
2898 }
2899
2900 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002901 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002902 + (lp != null ? lp.packageName : null)
2903 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2904 if (lp != null && lp.windowAnimations != 0) {
2905 // If this is a system resource, don't try to load it from the
2906 // application resources. It is nice to avoid loading application
2907 // resources if we can.
2908 String packageName = lp.packageName != null ? lp.packageName : "android";
2909 int resId = lp.windowAnimations;
2910 if ((resId&0xFF000000) == 0x01000000) {
2911 packageName = "android";
2912 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002913 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 + packageName);
2915 return AttributeCache.instance().get(packageName, resId,
2916 com.android.internal.R.styleable.WindowAnimation);
2917 }
2918 return null;
2919 }
Romain Guy06882f82009-06-10 13:36:04 -07002920
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002921 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002922 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002923 + packageName + " resId=0x" + Integer.toHexString(resId));
2924 if (packageName != null) {
2925 if ((resId&0xFF000000) == 0x01000000) {
2926 packageName = "android";
2927 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002928 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002929 + packageName);
2930 return AttributeCache.instance().get(packageName, resId,
2931 com.android.internal.R.styleable.WindowAnimation);
2932 }
2933 return null;
2934 }
2935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 private void applyEnterAnimationLocked(WindowState win) {
2937 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2938 if (win.mEnterAnimationPending) {
2939 win.mEnterAnimationPending = false;
2940 transit = WindowManagerPolicy.TRANSIT_ENTER;
2941 }
2942
2943 applyAnimationLocked(win, transit, true);
2944 }
2945
2946 private boolean applyAnimationLocked(WindowState win,
2947 int transit, boolean isEntrance) {
2948 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2949 // If we are trying to apply an animation, but already running
2950 // an animation of the same type, then just leave that one alone.
2951 return true;
2952 }
Romain Guy06882f82009-06-10 13:36:04 -07002953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 // Only apply an animation if the display isn't frozen. If it is
2955 // frozen, there is no reason to animate and it can cause strange
2956 // artifacts when we unfreeze the display if some different animation
2957 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002958 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 int anim = mPolicy.selectAnimationLw(win, transit);
2960 int attr = -1;
2961 Animation a = null;
2962 if (anim != 0) {
2963 a = AnimationUtils.loadAnimation(mContext, anim);
2964 } else {
2965 switch (transit) {
2966 case WindowManagerPolicy.TRANSIT_ENTER:
2967 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2968 break;
2969 case WindowManagerPolicy.TRANSIT_EXIT:
2970 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2971 break;
2972 case WindowManagerPolicy.TRANSIT_SHOW:
2973 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2974 break;
2975 case WindowManagerPolicy.TRANSIT_HIDE:
2976 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2977 break;
2978 }
2979 if (attr >= 0) {
2980 a = loadAnimation(win.mAttrs, attr);
2981 }
2982 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002983 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2985 + " mAnimation=" + win.mAnimation
2986 + " isEntrance=" + isEntrance);
2987 if (a != null) {
2988 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002989 RuntimeException e = null;
2990 if (!HIDE_STACK_CRAWLS) {
2991 e = new RuntimeException();
2992 e.fillInStackTrace();
2993 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002994 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
2996 win.setAnimation(a);
2997 win.mAnimationIsEntrance = isEntrance;
2998 }
2999 } else {
3000 win.clearAnimation();
3001 }
3002
3003 return win.mAnimation != null;
3004 }
3005
3006 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3007 int anim = 0;
3008 Context context = mContext;
3009 if (animAttr >= 0) {
3010 AttributeCache.Entry ent = getCachedAnimations(lp);
3011 if (ent != null) {
3012 context = ent.context;
3013 anim = ent.array.getResourceId(animAttr, 0);
3014 }
3015 }
3016 if (anim != 0) {
3017 return AnimationUtils.loadAnimation(context, anim);
3018 }
3019 return null;
3020 }
Romain Guy06882f82009-06-10 13:36:04 -07003021
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003022 private Animation loadAnimation(String packageName, int resId) {
3023 int anim = 0;
3024 Context context = mContext;
3025 if (resId >= 0) {
3026 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3027 if (ent != null) {
3028 context = ent.context;
3029 anim = resId;
3030 }
3031 }
3032 if (anim != 0) {
3033 return AnimationUtils.loadAnimation(context, anim);
3034 }
3035 return null;
3036 }
3037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 private boolean applyAnimationLocked(AppWindowToken wtoken,
3039 WindowManager.LayoutParams lp, int transit, boolean enter) {
3040 // Only apply an animation if the display isn't frozen. If it is
3041 // frozen, there is no reason to animate and it can cause strange
3042 // artifacts when we unfreeze the display if some different animation
3043 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003044 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003045 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003046 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003047 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003048 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003049 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003050 } else if (mNextAppTransitionPackage != null) {
3051 a = loadAnimation(mNextAppTransitionPackage, enter ?
3052 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003053 } else {
3054 int animAttr = 0;
3055 switch (transit) {
3056 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3057 animAttr = enter
3058 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3059 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3060 break;
3061 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3062 animAttr = enter
3063 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3064 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3065 break;
3066 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3067 animAttr = enter
3068 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3069 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3070 break;
3071 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3072 animAttr = enter
3073 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3074 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3075 break;
3076 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3077 animAttr = enter
3078 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3079 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3080 break;
3081 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3082 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003083 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003084 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3085 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003086 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003087 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003088 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3089 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003090 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003091 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003092 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003093 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3094 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3095 break;
3096 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3097 animAttr = enter
3098 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3099 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3100 break;
3101 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3102 animAttr = enter
3103 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3104 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003105 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003106 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003107 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003108 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003109 + " anim=" + a
3110 + " animAttr=0x" + Integer.toHexString(animAttr)
3111 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 if (a != null) {
3114 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003115 RuntimeException e = null;
3116 if (!HIDE_STACK_CRAWLS) {
3117 e = new RuntimeException();
3118 e.fillInStackTrace();
3119 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003120 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 }
3122 wtoken.setAnimation(a);
3123 }
3124 } else {
3125 wtoken.clearAnimation();
3126 }
3127
3128 return wtoken.animation != null;
3129 }
3130
3131 // -------------------------------------------------------------
3132 // Application Window Tokens
3133 // -------------------------------------------------------------
3134
3135 public void validateAppTokens(List tokens) {
3136 int v = tokens.size()-1;
3137 int m = mAppTokens.size()-1;
3138 while (v >= 0 && m >= 0) {
3139 AppWindowToken wtoken = mAppTokens.get(m);
3140 if (wtoken.removed) {
3141 m--;
3142 continue;
3143 }
3144 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3147 }
3148 v--;
3149 m--;
3150 }
3151 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003152 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 v--;
3154 }
3155 while (m >= 0) {
3156 AppWindowToken wtoken = mAppTokens.get(m);
3157 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003158 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 }
3160 m--;
3161 }
3162 }
3163
3164 boolean checkCallingPermission(String permission, String func) {
3165 // Quick check: if the calling permission is me, it's all okay.
3166 if (Binder.getCallingPid() == Process.myPid()) {
3167 return true;
3168 }
Romain Guy06882f82009-06-10 13:36:04 -07003169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003170 if (mContext.checkCallingPermission(permission)
3171 == PackageManager.PERMISSION_GRANTED) {
3172 return true;
3173 }
3174 String msg = "Permission Denial: " + func + " from pid="
3175 + Binder.getCallingPid()
3176 + ", uid=" + Binder.getCallingUid()
3177 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003178 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 return false;
3180 }
Romain Guy06882f82009-06-10 13:36:04 -07003181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003182 AppWindowToken findAppWindowToken(IBinder token) {
3183 WindowToken wtoken = mTokenMap.get(token);
3184 if (wtoken == null) {
3185 return null;
3186 }
3187 return wtoken.appWindowToken;
3188 }
Romain Guy06882f82009-06-10 13:36:04 -07003189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 public void addWindowToken(IBinder token, int type) {
3191 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3192 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003193 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 }
Romain Guy06882f82009-06-10 13:36:04 -07003195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 synchronized(mWindowMap) {
3197 WindowToken wtoken = mTokenMap.get(token);
3198 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003199 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 return;
3201 }
3202 wtoken = new WindowToken(token, type, true);
3203 mTokenMap.put(token, wtoken);
3204 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003205 if (type == TYPE_WALLPAPER) {
3206 mWallpaperTokens.add(wtoken);
3207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 }
3209 }
Romain Guy06882f82009-06-10 13:36:04 -07003210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003211 public void removeWindowToken(IBinder token) {
3212 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3213 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003214 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003215 }
3216
3217 final long origId = Binder.clearCallingIdentity();
3218 synchronized(mWindowMap) {
3219 WindowToken wtoken = mTokenMap.remove(token);
3220 mTokenList.remove(wtoken);
3221 if (wtoken != null) {
3222 boolean delayed = false;
3223 if (!wtoken.hidden) {
3224 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 final int N = wtoken.windows.size();
3227 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 for (int i=0; i<N; i++) {
3230 WindowState win = wtoken.windows.get(i);
3231
3232 if (win.isAnimating()) {
3233 delayed = true;
3234 }
Romain Guy06882f82009-06-10 13:36:04 -07003235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 if (win.isVisibleNow()) {
3237 applyAnimationLocked(win,
3238 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239 changed = true;
3240 }
3241 }
3242
3243 if (changed) {
3244 mLayoutNeeded = true;
3245 performLayoutAndPlaceSurfacesLocked();
3246 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3247 }
Romain Guy06882f82009-06-10 13:36:04 -07003248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 if (delayed) {
3250 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003251 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3252 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 }
3254 }
Romain Guy06882f82009-06-10 13:36:04 -07003255
Jeff Brownc5ed5912010-07-14 18:48:53 -07003256 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003257 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003258 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003259 }
3260 }
3261 Binder.restoreCallingIdentity(origId);
3262 }
3263
3264 public void addAppToken(int addPos, IApplicationToken token,
3265 int groupId, int requestedOrientation, boolean fullscreen) {
3266 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3267 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003268 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003269 }
Jeff Brown349703e2010-06-22 01:27:15 -07003270
3271 // Get the dispatching timeout here while we are not holding any locks so that it
3272 // can be cached by the AppWindowToken. The timeout value is used later by the
3273 // input dispatcher in code that does hold locks. If we did not cache the value
3274 // here we would run the chance of introducing a deadlock between the window manager
3275 // (which holds locks while updating the input dispatcher state) and the activity manager
3276 // (which holds locks while querying the application token).
3277 long inputDispatchingTimeoutNanos;
3278 try {
3279 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3280 } catch (RemoteException ex) {
3281 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3282 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3283 }
Romain Guy06882f82009-06-10 13:36:04 -07003284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 synchronized(mWindowMap) {
3286 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3287 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003288 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 return;
3290 }
3291 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003292 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 wtoken.groupId = groupId;
3294 wtoken.appFullscreen = fullscreen;
3295 wtoken.requestedOrientation = requestedOrientation;
3296 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003297 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 mTokenMap.put(token.asBinder(), wtoken);
3299 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003301 // Application tokens start out hidden.
3302 wtoken.hidden = true;
3303 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003305 //dump();
3306 }
3307 }
Romain Guy06882f82009-06-10 13:36:04 -07003308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 public void setAppGroupId(IBinder token, int groupId) {
3310 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3311 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003312 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313 }
3314
3315 synchronized(mWindowMap) {
3316 AppWindowToken wtoken = findAppWindowToken(token);
3317 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003318 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 return;
3320 }
3321 wtoken.groupId = groupId;
3322 }
3323 }
Romain Guy06882f82009-06-10 13:36:04 -07003324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 public int getOrientationFromWindowsLocked() {
3326 int pos = mWindows.size() - 1;
3327 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003328 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 pos--;
3330 if (wtoken.mAppToken != null) {
3331 // We hit an application window. so the orientation will be determined by the
3332 // app window. No point in continuing further.
3333 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3334 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003335 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 continue;
3337 }
3338 int req = wtoken.mAttrs.screenOrientation;
3339 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3340 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3341 continue;
3342 } else {
3343 return req;
3344 }
3345 }
3346 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3347 }
Romain Guy06882f82009-06-10 13:36:04 -07003348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003350 int pos = mAppTokens.size() - 1;
3351 int curGroup = 0;
3352 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3353 boolean findingBehind = false;
3354 boolean haveGroup = false;
3355 boolean lastFullscreen = false;
3356 while (pos >= 0) {
3357 AppWindowToken wtoken = mAppTokens.get(pos);
3358 pos--;
3359 // if we're about to tear down this window and not seek for
3360 // the behind activity, don't use it for orientation
3361 if (!findingBehind
3362 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3363 continue;
3364 }
3365
3366 if (!haveGroup) {
3367 // We ignore any hidden applications on the top.
3368 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003369 continue;
3370 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003371 haveGroup = true;
3372 curGroup = wtoken.groupId;
3373 lastOrientation = wtoken.requestedOrientation;
3374 } else if (curGroup != wtoken.groupId) {
3375 // If we have hit a new application group, and the bottom
3376 // of the previous group didn't explicitly say to use
3377 // the orientation behind it, and the last app was
3378 // full screen, then we'll stick with the
3379 // user's orientation.
3380 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3381 && lastFullscreen) {
3382 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003385 int or = wtoken.requestedOrientation;
3386 // If this application is fullscreen, and didn't explicitly say
3387 // to use the orientation behind it, then just take whatever
3388 // orientation it has and ignores whatever is under it.
3389 lastFullscreen = wtoken.appFullscreen;
3390 if (lastFullscreen
3391 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3392 return or;
3393 }
3394 // If this application has requested an explicit orientation,
3395 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003396 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3397 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003398 return or;
3399 }
3400 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3401 }
3402 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 }
Romain Guy06882f82009-06-10 13:36:04 -07003404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003406 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003407 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3408 "updateOrientationFromAppTokens()")) {
3409 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003411
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003412 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003413 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003414
3415 synchronized(mWindowMap) {
3416 if (updateOrientationFromAppTokensLocked()) {
3417 if (freezeThisOneIfNeeded != null) {
3418 AppWindowToken wtoken = findAppWindowToken(
3419 freezeThisOneIfNeeded);
3420 if (wtoken != null) {
3421 startAppFreezingScreenLocked(wtoken,
3422 ActivityInfo.CONFIG_ORIENTATION);
3423 }
3424 }
3425 config = computeNewConfigurationLocked();
3426
3427 } else if (currentConfig != null) {
3428 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003429 // state mismatches the activity manager's, update it,
3430 // disregarding font scale, which should remain set to
3431 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003432 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003433 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003434 if (computeNewConfigurationLocked(mTempConfiguration)) {
3435 if (currentConfig.diff(mTempConfiguration) != 0) {
3436 mWaitingForConfig = true;
3437 mLayoutNeeded = true;
3438 startFreezingDisplayLocked();
3439 config = new Configuration(mTempConfiguration);
3440 }
3441 }
3442 }
3443 }
3444
Dianne Hackborncfaef692009-06-15 14:24:44 -07003445 Binder.restoreCallingIdentity(ident);
3446 return config;
3447 }
3448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003450 * Determine the new desired orientation of the display, returning
3451 * a non-null new Configuration if it has changed from the current
3452 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3453 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3454 * SCREEN. This will typically be done for you if you call
3455 * sendNewConfiguration().
3456 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003457 * The orientation is computed from non-application windows first. If none of
3458 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003459 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3461 * android.os.IBinder)
3462 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003463 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003464 if (mDisplayFrozen) {
3465 // If the display is frozen, some activities may be in the middle
3466 // of restarting, and thus have removed their old window. If the
3467 // window has the flag to hide the lock screen, then the lock screen
3468 // can re-appear and inflict its own orientation on us. Keep the
3469 // orientation stable until this all settles down.
3470 return false;
3471 }
3472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 long ident = Binder.clearCallingIdentity();
3475 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003476 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003478 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 mForcedAppOrientation = req;
3480 //send a message to Policy indicating orientation change to take
3481 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003482 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003483 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3484 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3485 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 }
3487 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003488
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003489 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 } finally {
3491 Binder.restoreCallingIdentity(ident);
3492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 }
Romain Guy06882f82009-06-10 13:36:04 -07003494
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003495 int computeForcedAppOrientationLocked() {
3496 int req = getOrientationFromWindowsLocked();
3497 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3498 req = getOrientationFromAppTokensLocked();
3499 }
3500 return req;
3501 }
Romain Guy06882f82009-06-10 13:36:04 -07003502
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003503 public void setNewConfiguration(Configuration config) {
3504 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3505 "setNewConfiguration()")) {
3506 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3507 }
3508
3509 synchronized(mWindowMap) {
3510 mCurConfiguration = new Configuration(config);
3511 mWaitingForConfig = false;
3512 performLayoutAndPlaceSurfacesLocked();
3513 }
3514 }
3515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003516 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3517 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3518 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003519 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 }
Romain Guy06882f82009-06-10 13:36:04 -07003521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 synchronized(mWindowMap) {
3523 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3524 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003525 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 return;
3527 }
Romain Guy06882f82009-06-10 13:36:04 -07003528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 wtoken.requestedOrientation = requestedOrientation;
3530 }
3531 }
Romain Guy06882f82009-06-10 13:36:04 -07003532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 public int getAppOrientation(IApplicationToken token) {
3534 synchronized(mWindowMap) {
3535 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3536 if (wtoken == null) {
3537 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3538 }
Romain Guy06882f82009-06-10 13:36:04 -07003539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540 return wtoken.requestedOrientation;
3541 }
3542 }
Romain Guy06882f82009-06-10 13:36:04 -07003543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3545 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3546 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003547 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 }
3549
3550 synchronized(mWindowMap) {
3551 boolean changed = false;
3552 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003553 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 changed = mFocusedApp != null;
3555 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003556 if (changed) {
3557 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 } else {
3560 AppWindowToken newFocus = findAppWindowToken(token);
3561 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003562 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 return;
3564 }
3565 changed = mFocusedApp != newFocus;
3566 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003567 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003568 if (changed) {
3569 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 }
3572
3573 if (moveFocusNow && changed) {
3574 final long origId = Binder.clearCallingIdentity();
3575 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3576 Binder.restoreCallingIdentity(origId);
3577 }
3578 }
3579 }
3580
3581 public void prepareAppTransition(int transit) {
3582 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3583 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003584 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 }
Romain Guy06882f82009-06-10 13:36:04 -07003586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003587 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003588 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 TAG, "Prepare app transition: transit=" + transit
3590 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003591 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003592 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3593 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003595 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3596 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3597 // Opening a new task always supersedes a close for the anim.
3598 mNextAppTransition = transit;
3599 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3600 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3601 // Opening a new activity always supersedes a close for the anim.
3602 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 }
3604 mAppTransitionReady = false;
3605 mAppTransitionTimeout = false;
3606 mStartingIconInTransition = false;
3607 mSkipAppTransitionAnimation = false;
3608 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3609 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3610 5000);
3611 }
3612 }
3613 }
3614
3615 public int getPendingAppTransition() {
3616 return mNextAppTransition;
3617 }
Romain Guy06882f82009-06-10 13:36:04 -07003618
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003619 public void overridePendingAppTransition(String packageName,
3620 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003621 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003622 mNextAppTransitionPackage = packageName;
3623 mNextAppTransitionEnter = enterAnim;
3624 mNextAppTransitionExit = exitAnim;
3625 }
3626 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 public void executeAppTransition() {
3629 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3630 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003631 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 }
Romain Guy06882f82009-06-10 13:36:04 -07003633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003635 if (DEBUG_APP_TRANSITIONS) {
3636 RuntimeException e = new RuntimeException("here");
3637 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003638 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003639 + mNextAppTransition, e);
3640 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003641 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 mAppTransitionReady = true;
3643 final long origId = Binder.clearCallingIdentity();
3644 performLayoutAndPlaceSurfacesLocked();
3645 Binder.restoreCallingIdentity(origId);
3646 }
3647 }
3648 }
3649
3650 public void setAppStartingWindow(IBinder token, String pkg,
3651 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3652 IBinder transferFrom, boolean createIfNeeded) {
3653 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3654 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003655 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 }
3657
3658 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003659 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3661 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 AppWindowToken wtoken = findAppWindowToken(token);
3664 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003665 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 return;
3667 }
3668
3669 // If the display is frozen, we won't do anything until the
3670 // actual window is displayed so there is no reason to put in
3671 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003672 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 return;
3674 }
Romain Guy06882f82009-06-10 13:36:04 -07003675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 if (wtoken.startingData != null) {
3677 return;
3678 }
Romain Guy06882f82009-06-10 13:36:04 -07003679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 if (transferFrom != null) {
3681 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3682 if (ttoken != null) {
3683 WindowState startingWindow = ttoken.startingWindow;
3684 if (startingWindow != null) {
3685 if (mStartingIconInTransition) {
3686 // In this case, the starting icon has already
3687 // been displayed, so start letting windows get
3688 // shown immediately without any more transitions.
3689 mSkipAppTransitionAnimation = true;
3690 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 "Moving existing starting from " + ttoken
3693 + " to " + wtoken);
3694 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 // Transfer the starting window over to the new
3697 // token.
3698 wtoken.startingData = ttoken.startingData;
3699 wtoken.startingView = ttoken.startingView;
3700 wtoken.startingWindow = startingWindow;
3701 ttoken.startingData = null;
3702 ttoken.startingView = null;
3703 ttoken.startingWindow = null;
3704 ttoken.startingMoved = true;
3705 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003706 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003708 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003709 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003711 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 ttoken.windows.remove(startingWindow);
3713 ttoken.allAppWindows.remove(startingWindow);
3714 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 // Propagate other interesting state between the
3717 // tokens. If the old token is displayed, we should
3718 // immediately force the new one to be displayed. If
3719 // it is animating, we need to move that animation to
3720 // the new one.
3721 if (ttoken.allDrawn) {
3722 wtoken.allDrawn = true;
3723 }
3724 if (ttoken.firstWindowDrawn) {
3725 wtoken.firstWindowDrawn = true;
3726 }
3727 if (!ttoken.hidden) {
3728 wtoken.hidden = false;
3729 wtoken.hiddenRequested = false;
3730 wtoken.willBeHidden = false;
3731 }
3732 if (wtoken.clientHidden != ttoken.clientHidden) {
3733 wtoken.clientHidden = ttoken.clientHidden;
3734 wtoken.sendAppVisibilityToClients();
3735 }
3736 if (ttoken.animation != null) {
3737 wtoken.animation = ttoken.animation;
3738 wtoken.animating = ttoken.animating;
3739 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3740 ttoken.animation = null;
3741 ttoken.animLayerAdjustment = 0;
3742 wtoken.updateLayers();
3743 ttoken.updateLayers();
3744 }
Romain Guy06882f82009-06-10 13:36:04 -07003745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 mLayoutNeeded = true;
3748 performLayoutAndPlaceSurfacesLocked();
3749 Binder.restoreCallingIdentity(origId);
3750 return;
3751 } else if (ttoken.startingData != null) {
3752 // The previous app was getting ready to show a
3753 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003754 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 "Moving pending starting from " + ttoken
3756 + " to " + wtoken);
3757 wtoken.startingData = ttoken.startingData;
3758 ttoken.startingData = null;
3759 ttoken.startingMoved = true;
3760 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3761 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3762 // want to process the message ASAP, before any other queued
3763 // messages.
3764 mH.sendMessageAtFrontOfQueue(m);
3765 return;
3766 }
3767 }
3768 }
3769
3770 // There is no existing starting window, and the caller doesn't
3771 // want us to create one, so that's it!
3772 if (!createIfNeeded) {
3773 return;
3774 }
Romain Guy06882f82009-06-10 13:36:04 -07003775
Dianne Hackborn284ac932009-08-28 10:34:25 -07003776 // If this is a translucent or wallpaper window, then don't
3777 // show a starting window -- the current effect (a full-screen
3778 // opaque starting window that fades away to the real contents
3779 // when it is ready) does not work for this.
3780 if (theme != 0) {
3781 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3782 com.android.internal.R.styleable.Window);
3783 if (ent.array.getBoolean(
3784 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3785 return;
3786 }
3787 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003788 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3789 return;
3790 }
3791 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003792 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3793 return;
3794 }
3795 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 mStartingIconInTransition = true;
3798 wtoken.startingData = new StartingData(
3799 pkg, theme, nonLocalizedLabel,
3800 labelRes, icon);
3801 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3802 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3803 // want to process the message ASAP, before any other queued
3804 // messages.
3805 mH.sendMessageAtFrontOfQueue(m);
3806 }
3807 }
3808
3809 public void setAppWillBeHidden(IBinder token) {
3810 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3811 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003812 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003813 }
3814
3815 AppWindowToken wtoken;
3816
3817 synchronized(mWindowMap) {
3818 wtoken = findAppWindowToken(token);
3819 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003820 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 -08003821 return;
3822 }
3823 wtoken.willBeHidden = true;
3824 }
3825 }
Romain Guy06882f82009-06-10 13:36:04 -07003826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3828 boolean visible, int transit, boolean performLayout) {
3829 boolean delayed = false;
3830
3831 if (wtoken.clientHidden == visible) {
3832 wtoken.clientHidden = !visible;
3833 wtoken.sendAppVisibilityToClients();
3834 }
Romain Guy06882f82009-06-10 13:36:04 -07003835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 wtoken.willBeHidden = false;
3837 if (wtoken.hidden == visible) {
3838 final int N = wtoken.allAppWindows.size();
3839 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003840 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3842 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003845
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003846 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 if (wtoken.animation == sDummyAnimation) {
3848 wtoken.animation = null;
3849 }
3850 applyAnimationLocked(wtoken, lp, transit, visible);
3851 changed = true;
3852 if (wtoken.animation != null) {
3853 delayed = runningAppAnimation = true;
3854 }
3855 }
Romain Guy06882f82009-06-10 13:36:04 -07003856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857 for (int i=0; i<N; i++) {
3858 WindowState win = wtoken.allAppWindows.get(i);
3859 if (win == wtoken.startingWindow) {
3860 continue;
3861 }
3862
3863 if (win.isAnimating()) {
3864 delayed = true;
3865 }
Romain Guy06882f82009-06-10 13:36:04 -07003866
Joe Onorato8a9b2202010-02-26 18:56:32 -08003867 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 //win.dump(" ");
3869 if (visible) {
3870 if (!win.isVisibleNow()) {
3871 if (!runningAppAnimation) {
3872 applyAnimationLocked(win,
3873 WindowManagerPolicy.TRANSIT_ENTER, true);
3874 }
3875 changed = true;
3876 }
3877 } else if (win.isVisibleNow()) {
3878 if (!runningAppAnimation) {
3879 applyAnimationLocked(win,
3880 WindowManagerPolicy.TRANSIT_EXIT, false);
3881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 changed = true;
3883 }
3884 }
3885
3886 wtoken.hidden = wtoken.hiddenRequested = !visible;
3887 if (!visible) {
3888 unsetAppFreezingScreenLocked(wtoken, true, true);
3889 } else {
3890 // If we are being set visible, and the starting window is
3891 // not yet displayed, then make sure it doesn't get displayed.
3892 WindowState swin = wtoken.startingWindow;
3893 if (swin != null && (swin.mDrawPending
3894 || swin.mCommitDrawPending)) {
3895 swin.mPolicyVisibility = false;
3896 swin.mPolicyVisibilityAfterAnim = false;
3897 }
3898 }
Romain Guy06882f82009-06-10 13:36:04 -07003899
Joe Onorato8a9b2202010-02-26 18:56:32 -08003900 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3902 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003903
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003904 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003906 if (performLayout) {
3907 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3908 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07003909 } else {
3910 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 }
3913 }
3914
3915 if (wtoken.animation != null) {
3916 delayed = true;
3917 }
Romain Guy06882f82009-06-10 13:36:04 -07003918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 return delayed;
3920 }
3921
3922 public void setAppVisibility(IBinder token, boolean visible) {
3923 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3924 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003925 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003926 }
3927
3928 AppWindowToken wtoken;
3929
3930 synchronized(mWindowMap) {
3931 wtoken = findAppWindowToken(token);
3932 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003933 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003934 return;
3935 }
3936
3937 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003938 RuntimeException e = null;
3939 if (!HIDE_STACK_CRAWLS) {
3940 e = new RuntimeException();
3941 e.fillInStackTrace();
3942 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003943 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 + "): mNextAppTransition=" + mNextAppTransition
3945 + " hidden=" + wtoken.hidden
3946 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3947 }
Romain Guy06882f82009-06-10 13:36:04 -07003948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 // If we are preparing an app transition, then delay changing
3950 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003951 if (!mDisplayFrozen && mPolicy.isScreenOn()
3952 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 // Already in requested state, don't do anything more.
3954 if (wtoken.hiddenRequested != visible) {
3955 return;
3956 }
3957 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003958
Joe Onorato8a9b2202010-02-26 18:56:32 -08003959 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 TAG, "Setting dummy animation on: " + wtoken);
3961 wtoken.setDummyAnimation();
3962 mOpeningApps.remove(wtoken);
3963 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003964 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 wtoken.inPendingTransaction = true;
3966 if (visible) {
3967 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 wtoken.startingDisplayed = false;
3969 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003970
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003971 // If the token is currently hidden (should be the
3972 // common case), then we need to set up to wait for
3973 // its windows to be ready.
3974 if (wtoken.hidden) {
3975 wtoken.allDrawn = false;
3976 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003977
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003978 if (wtoken.clientHidden) {
3979 // In the case where we are making an app visible
3980 // but holding off for a transition, we still need
3981 // to tell the client to make its windows visible so
3982 // they get drawn. Otherwise, we will wait on
3983 // performing the transition until all windows have
3984 // been drawn, they never will be, and we are sad.
3985 wtoken.clientHidden = false;
3986 wtoken.sendAppVisibilityToClients();
3987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 }
3989 } else {
3990 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003991
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003992 // If the token is currently visible (should be the
3993 // common case), then set up to wait for it to be hidden.
3994 if (!wtoken.hidden) {
3995 wtoken.waitingToHide = true;
3996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 }
3998 return;
3999 }
Romain Guy06882f82009-06-10 13:36:04 -07004000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004001 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004002 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 wtoken.updateReportedVisibilityLocked();
4004 Binder.restoreCallingIdentity(origId);
4005 }
4006 }
4007
4008 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4009 boolean unfreezeSurfaceNow, boolean force) {
4010 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004011 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 + " force=" + force);
4013 final int N = wtoken.allAppWindows.size();
4014 boolean unfrozeWindows = false;
4015 for (int i=0; i<N; i++) {
4016 WindowState w = wtoken.allAppWindows.get(i);
4017 if (w.mAppFreezing) {
4018 w.mAppFreezing = false;
4019 if (w.mSurface != null && !w.mOrientationChanging) {
4020 w.mOrientationChanging = true;
4021 }
4022 unfrozeWindows = true;
4023 }
4024 }
4025 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004026 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 wtoken.freezingScreen = false;
4028 mAppsFreezingScreen--;
4029 }
4030 if (unfreezeSurfaceNow) {
4031 if (unfrozeWindows) {
4032 mLayoutNeeded = true;
4033 performLayoutAndPlaceSurfacesLocked();
4034 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004035 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 }
4037 }
4038 }
Romain Guy06882f82009-06-10 13:36:04 -07004039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4041 int configChanges) {
4042 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004043 RuntimeException e = null;
4044 if (!HIDE_STACK_CRAWLS) {
4045 e = new RuntimeException();
4046 e.fillInStackTrace();
4047 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004048 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 + ": hidden=" + wtoken.hidden + " freezing="
4050 + wtoken.freezingScreen, e);
4051 }
4052 if (!wtoken.hiddenRequested) {
4053 if (!wtoken.freezingScreen) {
4054 wtoken.freezingScreen = true;
4055 mAppsFreezingScreen++;
4056 if (mAppsFreezingScreen == 1) {
4057 startFreezingDisplayLocked();
4058 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4059 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4060 5000);
4061 }
4062 }
4063 final int N = wtoken.allAppWindows.size();
4064 for (int i=0; i<N; i++) {
4065 WindowState w = wtoken.allAppWindows.get(i);
4066 w.mAppFreezing = true;
4067 }
4068 }
4069 }
Romain Guy06882f82009-06-10 13:36:04 -07004070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 public void startAppFreezingScreen(IBinder token, int configChanges) {
4072 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4073 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004074 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 }
4076
4077 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004078 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004079 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 return;
4081 }
Romain Guy06882f82009-06-10 13:36:04 -07004082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 AppWindowToken wtoken = findAppWindowToken(token);
4084 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004085 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 return;
4087 }
4088 final long origId = Binder.clearCallingIdentity();
4089 startAppFreezingScreenLocked(wtoken, configChanges);
4090 Binder.restoreCallingIdentity(origId);
4091 }
4092 }
Romain Guy06882f82009-06-10 13:36:04 -07004093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 public void stopAppFreezingScreen(IBinder token, boolean force) {
4095 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4096 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004097 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 }
4099
4100 synchronized(mWindowMap) {
4101 AppWindowToken wtoken = findAppWindowToken(token);
4102 if (wtoken == null || wtoken.appToken == null) {
4103 return;
4104 }
4105 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004106 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4108 unsetAppFreezingScreenLocked(wtoken, true, force);
4109 Binder.restoreCallingIdentity(origId);
4110 }
4111 }
Romain Guy06882f82009-06-10 13:36:04 -07004112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004113 public void removeAppToken(IBinder token) {
4114 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4115 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004116 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004117 }
4118
4119 AppWindowToken wtoken = null;
4120 AppWindowToken startingToken = null;
4121 boolean delayed = false;
4122
4123 final long origId = Binder.clearCallingIdentity();
4124 synchronized(mWindowMap) {
4125 WindowToken basewtoken = mTokenMap.remove(token);
4126 mTokenList.remove(basewtoken);
4127 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004128 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004129 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 wtoken.inPendingTransaction = false;
4131 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004132 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 if (mClosingApps.contains(wtoken)) {
4134 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004135 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004137 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 delayed = true;
4139 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004140 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 TAG, "Removing app " + wtoken + " delayed=" + delayed
4142 + " animation=" + wtoken.animation
4143 + " animating=" + wtoken.animating);
4144 if (delayed) {
4145 // set the token aside because it has an active animation to be finished
4146 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004147 } else {
4148 // Make sure there is no animation running on this token,
4149 // so any windows associated with it will be removed as
4150 // soon as their animations are complete
4151 wtoken.animation = null;
4152 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004153 }
4154 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004155 if (mLastEnterAnimToken == wtoken) {
4156 mLastEnterAnimToken = null;
4157 mLastEnterAnimParams = null;
4158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004159 wtoken.removed = true;
4160 if (wtoken.startingData != null) {
4161 startingToken = wtoken;
4162 }
4163 unsetAppFreezingScreenLocked(wtoken, true, true);
4164 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 mFocusedApp = null;
4167 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004168 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 }
4170 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004171 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 }
Romain Guy06882f82009-06-10 13:36:04 -07004173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 if (!delayed && wtoken != null) {
4175 wtoken.updateReportedVisibilityLocked();
4176 }
4177 }
4178 Binder.restoreCallingIdentity(origId);
4179
4180 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004181 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004182 + startingToken + ": app token removed");
4183 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4184 mH.sendMessage(m);
4185 }
4186 }
4187
4188 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4189 final int NW = token.windows.size();
4190 for (int i=0; i<NW; i++) {
4191 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004192 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004194 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 int j = win.mChildWindows.size();
4196 while (j > 0) {
4197 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004198 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004199 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004200 "Tmp removing child window " + cwin);
4201 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004202 }
4203 }
4204 return NW > 0;
4205 }
4206
4207 void dumpAppTokensLocked() {
4208 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004209 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 }
4211 }
Romain Guy06882f82009-06-10 13:36:04 -07004212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213 void dumpWindowsLocked() {
4214 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004215 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 }
4217 }
Romain Guy06882f82009-06-10 13:36:04 -07004218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 private int findWindowOffsetLocked(int tokenPos) {
4220 final int NW = mWindows.size();
4221
4222 if (tokenPos >= mAppTokens.size()) {
4223 int i = NW;
4224 while (i > 0) {
4225 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004226 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004227 if (win.getAppToken() != null) {
4228 return i+1;
4229 }
4230 }
4231 }
4232
4233 while (tokenPos > 0) {
4234 // Find the first app token below the new position that has
4235 // a window displayed.
4236 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004237 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004239 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004240 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004241 "Skipping token -- currently sending to bottom");
4242 tokenPos--;
4243 continue;
4244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004245 int i = wtoken.windows.size();
4246 while (i > 0) {
4247 i--;
4248 WindowState win = wtoken.windows.get(i);
4249 int j = win.mChildWindows.size();
4250 while (j > 0) {
4251 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004252 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004253 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 for (int pos=NW-1; pos>=0; pos--) {
4255 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004256 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 "Found child win @" + (pos+1));
4258 return pos+1;
4259 }
4260 }
4261 }
4262 }
4263 for (int pos=NW-1; pos>=0; pos--) {
4264 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004265 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 return pos+1;
4267 }
4268 }
4269 }
4270 tokenPos--;
4271 }
4272
4273 return 0;
4274 }
4275
4276 private final int reAddWindowLocked(int index, WindowState win) {
4277 final int NCW = win.mChildWindows.size();
4278 boolean added = false;
4279 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004280 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004282 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004283 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 mWindows.add(index, win);
4285 index++;
4286 added = true;
4287 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004288 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004289 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 mWindows.add(index, cwin);
4291 index++;
4292 }
4293 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004294 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004295 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 mWindows.add(index, win);
4297 index++;
4298 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004299 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 return index;
4301 }
Romain Guy06882f82009-06-10 13:36:04 -07004302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4304 final int NW = token.windows.size();
4305 for (int i=0; i<NW; i++) {
4306 index = reAddWindowLocked(index, token.windows.get(i));
4307 }
4308 return index;
4309 }
4310
4311 public void moveAppToken(int index, IBinder token) {
4312 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4313 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004314 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 }
4316
4317 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004318 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 if (DEBUG_REORDER) dumpAppTokensLocked();
4320 final AppWindowToken wtoken = findAppWindowToken(token);
4321 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004322 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 + token + " (" + wtoken + ")");
4324 return;
4325 }
4326 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004327 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004328 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004331 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 if (DEBUG_REORDER) dumpWindowsLocked();
4333 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004334 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 if (DEBUG_REORDER) dumpWindowsLocked();
4336 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004337 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 if (DEBUG_REORDER) dumpWindowsLocked();
4339 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 mLayoutNeeded = true;
4341 performLayoutAndPlaceSurfacesLocked();
4342 }
4343 Binder.restoreCallingIdentity(origId);
4344 }
4345 }
4346
4347 private void removeAppTokensLocked(List<IBinder> tokens) {
4348 // XXX This should be done more efficiently!
4349 // (take advantage of the fact that both lists should be
4350 // ordered in the same way.)
4351 int N = tokens.size();
4352 for (int i=0; i<N; i++) {
4353 IBinder token = tokens.get(i);
4354 final AppWindowToken wtoken = findAppWindowToken(token);
4355 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004356 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 + token + " (" + wtoken + ")");
4358 i--;
4359 N--;
4360 }
4361 }
4362 }
4363
Dianne Hackborna8f60182009-09-01 19:01:50 -07004364 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4365 boolean updateFocusAndLayout) {
4366 // First remove all of the windows from the list.
4367 tmpRemoveAppWindowsLocked(wtoken);
4368
4369 // Where to start adding?
4370 int pos = findWindowOffsetLocked(tokenPos);
4371
4372 // And now add them back at the correct place.
4373 pos = reAddAppWindowsLocked(pos, wtoken);
4374
4375 if (updateFocusAndLayout) {
4376 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4377 assignLayersLocked();
4378 }
4379 mLayoutNeeded = true;
4380 performLayoutAndPlaceSurfacesLocked();
4381 }
4382 }
4383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4385 // First remove all of the windows from the list.
4386 final int N = tokens.size();
4387 int i;
4388 for (i=0; i<N; i++) {
4389 WindowToken token = mTokenMap.get(tokens.get(i));
4390 if (token != null) {
4391 tmpRemoveAppWindowsLocked(token);
4392 }
4393 }
4394
4395 // Where to start adding?
4396 int pos = findWindowOffsetLocked(tokenPos);
4397
4398 // And now add them back at the correct place.
4399 for (i=0; i<N; i++) {
4400 WindowToken token = mTokenMap.get(tokens.get(i));
4401 if (token != null) {
4402 pos = reAddAppWindowsLocked(pos, token);
4403 }
4404 }
4405
Dianne Hackborna8f60182009-09-01 19:01:50 -07004406 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4407 assignLayersLocked();
4408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 mLayoutNeeded = true;
4410 performLayoutAndPlaceSurfacesLocked();
4411
4412 //dump();
4413 }
4414
4415 public void moveAppTokensToTop(List<IBinder> tokens) {
4416 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4417 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004418 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 }
4420
4421 final long origId = Binder.clearCallingIdentity();
4422 synchronized(mWindowMap) {
4423 removeAppTokensLocked(tokens);
4424 final int N = tokens.size();
4425 for (int i=0; i<N; i++) {
4426 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4427 if (wt != null) {
4428 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004429 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004430 mToTopApps.remove(wt);
4431 mToBottomApps.remove(wt);
4432 mToTopApps.add(wt);
4433 wt.sendingToBottom = false;
4434 wt.sendingToTop = true;
4435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
4437 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004438
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004439 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004440 moveAppWindowsLocked(tokens, mAppTokens.size());
4441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 }
4443 Binder.restoreCallingIdentity(origId);
4444 }
4445
4446 public void moveAppTokensToBottom(List<IBinder> tokens) {
4447 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4448 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004449 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
4451
4452 final long origId = Binder.clearCallingIdentity();
4453 synchronized(mWindowMap) {
4454 removeAppTokensLocked(tokens);
4455 final int N = tokens.size();
4456 int pos = 0;
4457 for (int i=0; i<N; i++) {
4458 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4459 if (wt != null) {
4460 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004461 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004462 mToTopApps.remove(wt);
4463 mToBottomApps.remove(wt);
4464 mToBottomApps.add(i, wt);
4465 wt.sendingToTop = false;
4466 wt.sendingToBottom = true;
4467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 pos++;
4469 }
4470 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004471
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004472 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004473 moveAppWindowsLocked(tokens, 0);
4474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
4476 Binder.restoreCallingIdentity(origId);
4477 }
4478
4479 // -------------------------------------------------------------
4480 // Misc IWindowSession methods
4481 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004482
Jim Miller284b62e2010-06-08 14:27:42 -07004483 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004484 {
Jim Miller284b62e2010-06-08 14:27:42 -07004485 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4486 // called before DevicePolicyManagerService has started.
4487 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4488 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4489 Context.DEVICE_POLICY_SERVICE);
4490 if (dpm != null) {
4491 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4492 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4493 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4494 }
Jim Millerd6b57052010-06-07 17:52:42 -07004495 }
Jim Miller284b62e2010-06-08 14:27:42 -07004496 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004497 }
4498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004500 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 != PackageManager.PERMISSION_GRANTED) {
4502 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4503 }
Jim Millerd6b57052010-06-07 17:52:42 -07004504
Jim Miller284b62e2010-06-08 14:27:42 -07004505 synchronized (mKeyguardTokenWatcher) {
4506 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 }
4509
4510 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004511 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 != PackageManager.PERMISSION_GRANTED) {
4513 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515
Jim Miller284b62e2010-06-08 14:27:42 -07004516 synchronized (mKeyguardTokenWatcher) {
4517 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004518
Jim Miller284b62e2010-06-08 14:27:42 -07004519 if (!mKeyguardTokenWatcher.isAcquired()) {
4520 // If we are the last one to reenable the keyguard wait until
4521 // we have actually finished reenabling until returning.
4522 // It is possible that reenableKeyguard() can be called before
4523 // the previous disableKeyguard() is handled, in which case
4524 // neither mKeyguardTokenWatcher.acquired() or released() would
4525 // be called. In that case mKeyguardDisabled will be false here
4526 // and we have nothing to wait for.
4527 while (mKeyguardDisabled) {
4528 try {
4529 mKeyguardTokenWatcher.wait();
4530 } catch (InterruptedException e) {
4531 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 }
4533 }
4534 }
4535 }
4536 }
4537
4538 /**
4539 * @see android.app.KeyguardManager#exitKeyguardSecurely
4540 */
4541 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004542 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 != PackageManager.PERMISSION_GRANTED) {
4544 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4545 }
4546 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4547 public void onKeyguardExitResult(boolean success) {
4548 try {
4549 callback.onKeyguardExitResult(success);
4550 } catch (RemoteException e) {
4551 // Client has died, we don't care.
4552 }
4553 }
4554 });
4555 }
4556
4557 public boolean inKeyguardRestrictedInputMode() {
4558 return mPolicy.inKeyguardRestrictedKeyInputMode();
4559 }
Romain Guy06882f82009-06-10 13:36:04 -07004560
Dianne Hackbornffa42482009-09-23 22:20:11 -07004561 public void closeSystemDialogs(String reason) {
4562 synchronized(mWindowMap) {
4563 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004564 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004565 if (w.mSurface != null) {
4566 try {
4567 w.mClient.closeSystemDialogs(reason);
4568 } catch (RemoteException e) {
4569 }
4570 }
4571 }
4572 }
4573 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 static float fixScale(float scale) {
4576 if (scale < 0) scale = 0;
4577 else if (scale > 20) scale = 20;
4578 return Math.abs(scale);
4579 }
Romain Guy06882f82009-06-10 13:36:04 -07004580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 public void setAnimationScale(int which, float scale) {
4582 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4583 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004584 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004585 }
4586
4587 if (scale < 0) scale = 0;
4588 else if (scale > 20) scale = 20;
4589 scale = Math.abs(scale);
4590 switch (which) {
4591 case 0: mWindowAnimationScale = fixScale(scale); break;
4592 case 1: mTransitionAnimationScale = fixScale(scale); break;
4593 }
Romain Guy06882f82009-06-10 13:36:04 -07004594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 // Persist setting
4596 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4597 }
Romain Guy06882f82009-06-10 13:36:04 -07004598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 public void setAnimationScales(float[] scales) {
4600 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4601 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004602 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
4604
4605 if (scales != null) {
4606 if (scales.length >= 1) {
4607 mWindowAnimationScale = fixScale(scales[0]);
4608 }
4609 if (scales.length >= 2) {
4610 mTransitionAnimationScale = fixScale(scales[1]);
4611 }
4612 }
Romain Guy06882f82009-06-10 13:36:04 -07004613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 // Persist setting
4615 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4616 }
Romain Guy06882f82009-06-10 13:36:04 -07004617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 public float getAnimationScale(int which) {
4619 switch (which) {
4620 case 0: return mWindowAnimationScale;
4621 case 1: return mTransitionAnimationScale;
4622 }
4623 return 0;
4624 }
Romain Guy06882f82009-06-10 13:36:04 -07004625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 public float[] getAnimationScales() {
4627 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4628 }
Romain Guy06882f82009-06-10 13:36:04 -07004629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 public int getSwitchState(int sw) {
4631 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4632 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004633 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004635 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 }
Romain Guy06882f82009-06-10 13:36:04 -07004637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 public int getSwitchStateForDevice(int devid, int sw) {
4639 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4640 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004641 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004643 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004644 }
Romain Guy06882f82009-06-10 13:36:04 -07004645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 public int getScancodeState(int sw) {
4647 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4648 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004649 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004651 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 }
Romain Guy06882f82009-06-10 13:36:04 -07004653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 public int getScancodeStateForDevice(int devid, int sw) {
4655 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4656 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004657 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004659 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 }
Romain Guy06882f82009-06-10 13:36:04 -07004661
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004662 public int getTrackballScancodeState(int sw) {
4663 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4664 "getTrackballScancodeState()")) {
4665 throw new SecurityException("Requires READ_INPUT_STATE permission");
4666 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004667 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004668 }
4669
4670 public int getDPadScancodeState(int sw) {
4671 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4672 "getDPadScancodeState()")) {
4673 throw new SecurityException("Requires READ_INPUT_STATE permission");
4674 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004675 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004676 }
4677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 public int getKeycodeState(int sw) {
4679 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4680 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004681 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004683 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 }
Romain Guy06882f82009-06-10 13:36:04 -07004685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 public int getKeycodeStateForDevice(int devid, int sw) {
4687 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4688 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004689 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004691 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 }
Romain Guy06882f82009-06-10 13:36:04 -07004693
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004694 public int getTrackballKeycodeState(int sw) {
4695 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4696 "getTrackballKeycodeState()")) {
4697 throw new SecurityException("Requires READ_INPUT_STATE permission");
4698 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004699 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004700 }
4701
4702 public int getDPadKeycodeState(int sw) {
4703 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4704 "getDPadKeycodeState()")) {
4705 throw new SecurityException("Requires READ_INPUT_STATE permission");
4706 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004707 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004708 }
Jeff Browna41ca772010-08-11 14:46:32 -07004709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004711 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 }
Romain Guy06882f82009-06-10 13:36:04 -07004713
Jeff Browna41ca772010-08-11 14:46:32 -07004714 public InputChannel monitorInput(String inputChannelName) {
4715 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4716 "monitorInput()")) {
4717 throw new SecurityException("Requires READ_INPUT_STATE permission");
4718 }
4719 return mInputManager.monitorInput(inputChannelName);
4720 }
4721
Jeff Brown8d608662010-08-30 03:02:23 -07004722 public InputDevice getInputDevice(int deviceId) {
4723 return mInputManager.getInputDevice(deviceId);
4724 }
4725
4726 public int[] getInputDeviceIds() {
4727 return mInputManager.getInputDeviceIds();
4728 }
4729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004730 public void enableScreenAfterBoot() {
4731 synchronized(mWindowMap) {
4732 if (mSystemBooted) {
4733 return;
4734 }
4735 mSystemBooted = true;
4736 }
Romain Guy06882f82009-06-10 13:36:04 -07004737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 performEnableScreen();
4739 }
Romain Guy06882f82009-06-10 13:36:04 -07004740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 public void enableScreenIfNeededLocked() {
4742 if (mDisplayEnabled) {
4743 return;
4744 }
4745 if (!mSystemBooted) {
4746 return;
4747 }
4748 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4749 }
Romain Guy06882f82009-06-10 13:36:04 -07004750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 public void performEnableScreen() {
4752 synchronized(mWindowMap) {
4753 if (mDisplayEnabled) {
4754 return;
4755 }
4756 if (!mSystemBooted) {
4757 return;
4758 }
Romain Guy06882f82009-06-10 13:36:04 -07004759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 // Don't enable the screen until all existing windows
4761 // have been drawn.
4762 final int N = mWindows.size();
4763 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004764 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004765 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004766 return;
4767 }
4768 }
Romain Guy06882f82009-06-10 13:36:04 -07004769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 mDisplayEnabled = true;
4771 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004772 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 StringWriter sw = new StringWriter();
4774 PrintWriter pw = new PrintWriter(sw);
4775 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004776 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004777 }
4778 try {
4779 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4780 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004781 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004782 Parcel data = Parcel.obtain();
4783 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4784 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4785 data, null, 0);
4786 data.recycle();
4787 }
4788 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004789 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 }
4791 }
Romain Guy06882f82009-06-10 13:36:04 -07004792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004796 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4797 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004798 }
Romain Guy06882f82009-06-10 13:36:04 -07004799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 public void setInTouchMode(boolean mode) {
4801 synchronized(mWindowMap) {
4802 mInTouchMode = mode;
4803 }
4804 }
4805
Romain Guy06882f82009-06-10 13:36:04 -07004806 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004807 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004809 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004810 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004811 }
4812
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004813 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 }
Romain Guy06882f82009-06-10 13:36:04 -07004815
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004816 public void setRotationUnchecked(int rotation,
4817 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004818 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004819 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 long origId = Binder.clearCallingIdentity();
4822 boolean changed;
4823 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004824 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004825 }
Romain Guy06882f82009-06-10 13:36:04 -07004826
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004827 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004828 sendNewConfiguration();
4829 }
Romain Guy06882f82009-06-10 13:36:04 -07004830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 Binder.restoreCallingIdentity(origId);
4832 }
Romain Guy06882f82009-06-10 13:36:04 -07004833
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004834 /**
4835 * Apply a new rotation to the screen, respecting the requests of
4836 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4837 * re-evaluate the desired rotation.
4838 *
4839 * Returns null if the rotation has been changed. In this case YOU
4840 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4841 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004842 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 boolean changed;
4844 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4845 rotation = mRequestedRotation;
4846 } else {
4847 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004848 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004850 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004851 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004853 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004857 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 "Rotation changed to " + rotation
4859 + " from " + mRotation
4860 + " (forceApp=" + mForcedAppOrientation
4861 + ", req=" + mRequestedRotation + ")");
4862 mRotation = rotation;
4863 mWindowsFreezingScreen = true;
4864 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4865 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4866 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004867 mWaitingForConfig = true;
4868 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004870 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004871 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004873 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 }
4875 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004876 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004877 if (w.mSurface != null) {
4878 w.mOrientationChanging = true;
4879 }
4880 }
4881 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4882 try {
4883 mRotationWatchers.get(i).onRotationChanged(rotation);
4884 } catch (RemoteException e) {
4885 }
4886 }
4887 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 return changed;
4890 }
Romain Guy06882f82009-06-10 13:36:04 -07004891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 public int getRotation() {
4893 return mRotation;
4894 }
4895
4896 public int watchRotation(IRotationWatcher watcher) {
4897 final IBinder watcherBinder = watcher.asBinder();
4898 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4899 public void binderDied() {
4900 synchronized (mWindowMap) {
4901 for (int i=0; i<mRotationWatchers.size(); i++) {
4902 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004903 IRotationWatcher removed = mRotationWatchers.remove(i);
4904 if (removed != null) {
4905 removed.asBinder().unlinkToDeath(this, 0);
4906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 i--;
4908 }
4909 }
4910 }
4911 }
4912 };
Romain Guy06882f82009-06-10 13:36:04 -07004913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 synchronized (mWindowMap) {
4915 try {
4916 watcher.asBinder().linkToDeath(dr, 0);
4917 mRotationWatchers.add(watcher);
4918 } catch (RemoteException e) {
4919 // Client died, no cleanup needed.
4920 }
Romain Guy06882f82009-06-10 13:36:04 -07004921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 return mRotation;
4923 }
4924 }
4925
4926 /**
4927 * Starts the view server on the specified port.
4928 *
4929 * @param port The port to listener to.
4930 *
4931 * @return True if the server was successfully started, false otherwise.
4932 *
4933 * @see com.android.server.ViewServer
4934 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4935 */
4936 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004937 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 return false;
4939 }
4940
4941 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4942 return false;
4943 }
4944
4945 if (port < 1024) {
4946 return false;
4947 }
4948
4949 if (mViewServer != null) {
4950 if (!mViewServer.isRunning()) {
4951 try {
4952 return mViewServer.start();
4953 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004954 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004955 }
4956 }
4957 return false;
4958 }
4959
4960 try {
4961 mViewServer = new ViewServer(this, port);
4962 return mViewServer.start();
4963 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004964 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 }
4966 return false;
4967 }
4968
Romain Guy06882f82009-06-10 13:36:04 -07004969 private boolean isSystemSecure() {
4970 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4971 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4972 }
4973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004974 /**
4975 * Stops the view server if it exists.
4976 *
4977 * @return True if the server stopped, false if it wasn't started or
4978 * couldn't be stopped.
4979 *
4980 * @see com.android.server.ViewServer
4981 */
4982 public boolean stopViewServer() {
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, "stopViewServer")) {
4988 return false;
4989 }
4990
4991 if (mViewServer != null) {
4992 return mViewServer.stop();
4993 }
4994 return false;
4995 }
4996
4997 /**
4998 * Indicates whether the view server is running.
4999 *
5000 * @return True if the server is running, false otherwise.
5001 *
5002 * @see com.android.server.ViewServer
5003 */
5004 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005005 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006 return false;
5007 }
5008
5009 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5010 return false;
5011 }
5012
5013 return mViewServer != null && mViewServer.isRunning();
5014 }
5015
5016 /**
5017 * Lists all availble windows in the system. The listing is written in the
5018 * specified Socket's output stream with the following syntax:
5019 * windowHashCodeInHexadecimal windowName
5020 * Each line of the ouput represents a different window.
5021 *
5022 * @param client The remote client to send the listing to.
5023 * @return False if an error occured, true otherwise.
5024 */
5025 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005026 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 return false;
5028 }
5029
5030 boolean result = true;
5031
Jeff Browne33348b2010-07-15 23:54:05 -07005032 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005034 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005035 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005036 }
5037
5038 BufferedWriter out = null;
5039
5040 // Any uncaught exception will crash the system process
5041 try {
5042 OutputStream clientStream = client.getOutputStream();
5043 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5044
5045 final int count = windows.length;
5046 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005047 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005048 out.write(Integer.toHexString(System.identityHashCode(w)));
5049 out.write(' ');
5050 out.append(w.mAttrs.getTitle());
5051 out.write('\n');
5052 }
5053
5054 out.write("DONE.\n");
5055 out.flush();
5056 } catch (Exception e) {
5057 result = false;
5058 } finally {
5059 if (out != null) {
5060 try {
5061 out.close();
5062 } catch (IOException e) {
5063 result = false;
5064 }
5065 }
5066 }
5067
5068 return result;
5069 }
5070
5071 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005072 * Returns the focused window in the following format:
5073 * windowHashCodeInHexadecimal windowName
5074 *
5075 * @param client The remote client to send the listing to.
5076 * @return False if an error occurred, true otherwise.
5077 */
5078 boolean viewServerGetFocusedWindow(Socket client) {
5079 if (isSystemSecure()) {
5080 return false;
5081 }
5082
5083 boolean result = true;
5084
5085 WindowState focusedWindow = getFocusedWindow();
5086
5087 BufferedWriter out = null;
5088
5089 // Any uncaught exception will crash the system process
5090 try {
5091 OutputStream clientStream = client.getOutputStream();
5092 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5093
5094 if(focusedWindow != null) {
5095 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5096 out.write(' ');
5097 out.append(focusedWindow.mAttrs.getTitle());
5098 }
5099 out.write('\n');
5100 out.flush();
5101 } catch (Exception e) {
5102 result = false;
5103 } finally {
5104 if (out != null) {
5105 try {
5106 out.close();
5107 } catch (IOException e) {
5108 result = false;
5109 }
5110 }
5111 }
5112
5113 return result;
5114 }
5115
5116 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 * Sends a command to a target window. The result of the command, if any, will be
5118 * written in the output stream of the specified socket.
5119 *
5120 * The parameters must follow this syntax:
5121 * windowHashcode extra
5122 *
5123 * Where XX is the length in characeters of the windowTitle.
5124 *
5125 * The first parameter is the target window. The window with the specified hashcode
5126 * will be the target. If no target can be found, nothing happens. The extra parameters
5127 * will be delivered to the target window and as parameters to the command itself.
5128 *
5129 * @param client The remote client to sent the result, if any, to.
5130 * @param command The command to execute.
5131 * @param parameters The command parameters.
5132 *
5133 * @return True if the command was successfully delivered, false otherwise. This does
5134 * not indicate whether the command itself was successful.
5135 */
5136 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005137 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005138 return false;
5139 }
5140
5141 boolean success = true;
5142 Parcel data = null;
5143 Parcel reply = null;
5144
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005145 BufferedWriter out = null;
5146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005147 // Any uncaught exception will crash the system process
5148 try {
5149 // Find the hashcode of the window
5150 int index = parameters.indexOf(' ');
5151 if (index == -1) {
5152 index = parameters.length();
5153 }
5154 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005155 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156
5157 // Extract the command's parameter after the window description
5158 if (index < parameters.length()) {
5159 parameters = parameters.substring(index + 1);
5160 } else {
5161 parameters = "";
5162 }
5163
5164 final WindowManagerService.WindowState window = findWindow(hashCode);
5165 if (window == null) {
5166 return false;
5167 }
5168
5169 data = Parcel.obtain();
5170 data.writeInterfaceToken("android.view.IWindow");
5171 data.writeString(command);
5172 data.writeString(parameters);
5173 data.writeInt(1);
5174 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5175
5176 reply = Parcel.obtain();
5177
5178 final IBinder binder = window.mClient.asBinder();
5179 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5180 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5181
5182 reply.readException();
5183
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005184 if (!client.isOutputShutdown()) {
5185 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5186 out.write("DONE\n");
5187 out.flush();
5188 }
5189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005190 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005191 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 success = false;
5193 } finally {
5194 if (data != null) {
5195 data.recycle();
5196 }
5197 if (reply != null) {
5198 reply.recycle();
5199 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005200 if (out != null) {
5201 try {
5202 out.close();
5203 } catch (IOException e) {
5204
5205 }
5206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 }
5208
5209 return success;
5210 }
5211
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005212 public void addWindowChangeListener(WindowChangeListener listener) {
5213 synchronized(mWindowMap) {
5214 mWindowChangeListeners.add(listener);
5215 }
5216 }
5217
5218 public void removeWindowChangeListener(WindowChangeListener listener) {
5219 synchronized(mWindowMap) {
5220 mWindowChangeListeners.remove(listener);
5221 }
5222 }
5223
5224 private void notifyWindowsChanged() {
5225 WindowChangeListener[] windowChangeListeners;
5226 synchronized(mWindowMap) {
5227 if(mWindowChangeListeners.isEmpty()) {
5228 return;
5229 }
5230 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5231 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5232 }
5233 int N = windowChangeListeners.length;
5234 for(int i = 0; i < N; i++) {
5235 windowChangeListeners[i].windowsChanged();
5236 }
5237 }
5238
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005239 private void notifyFocusChanged() {
5240 WindowChangeListener[] windowChangeListeners;
5241 synchronized(mWindowMap) {
5242 if(mWindowChangeListeners.isEmpty()) {
5243 return;
5244 }
5245 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5246 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5247 }
5248 int N = windowChangeListeners.length;
5249 for(int i = 0; i < N; i++) {
5250 windowChangeListeners[i].focusChanged();
5251 }
5252 }
5253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 private WindowState findWindow(int hashCode) {
5255 if (hashCode == -1) {
5256 return getFocusedWindow();
5257 }
5258
5259 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005260 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 final int count = windows.size();
5262
5263 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005264 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005265 if (System.identityHashCode(w) == hashCode) {
5266 return w;
5267 }
5268 }
5269 }
5270
5271 return null;
5272 }
5273
5274 /*
5275 * Instruct the Activity Manager to fetch the current configuration and broadcast
5276 * that to config-changed listeners if appropriate.
5277 */
5278 void sendNewConfiguration() {
5279 try {
5280 mActivityManager.updateConfiguration(null);
5281 } catch (RemoteException e) {
5282 }
5283 }
Romain Guy06882f82009-06-10 13:36:04 -07005284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 public Configuration computeNewConfiguration() {
5286 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005287 return computeNewConfigurationLocked();
5288 }
5289 }
Romain Guy06882f82009-06-10 13:36:04 -07005290
Dianne Hackbornc485a602009-03-24 22:39:49 -07005291 Configuration computeNewConfigurationLocked() {
5292 Configuration config = new Configuration();
5293 if (!computeNewConfigurationLocked(config)) {
5294 return null;
5295 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005296 return config;
5297 }
Romain Guy06882f82009-06-10 13:36:04 -07005298
Dianne Hackbornc485a602009-03-24 22:39:49 -07005299 boolean computeNewConfigurationLocked(Configuration config) {
5300 if (mDisplay == null) {
5301 return false;
5302 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005303
5304 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005305
5306 // Use the effective "visual" dimensions based on current rotation
5307 final boolean rotated = (mRotation == Surface.ROTATION_90
5308 || mRotation == Surface.ROTATION_270);
5309 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5310 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5311
Dianne Hackbornc485a602009-03-24 22:39:49 -07005312 int orientation = Configuration.ORIENTATION_SQUARE;
5313 if (dw < dh) {
5314 orientation = Configuration.ORIENTATION_PORTRAIT;
5315 } else if (dw > dh) {
5316 orientation = Configuration.ORIENTATION_LANDSCAPE;
5317 }
5318 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005319
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005320 DisplayMetrics dm = new DisplayMetrics();
5321 mDisplay.getMetrics(dm);
5322 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5323
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005324 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005325 // Note we only do this once because at this point we don't
5326 // expect the screen to change in this way at runtime, and want
5327 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005328 int longSize = dw;
5329 int shortSize = dh;
5330 if (longSize < shortSize) {
5331 int tmp = longSize;
5332 longSize = shortSize;
5333 shortSize = tmp;
5334 }
5335 longSize = (int)(longSize/dm.density);
5336 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005337
Dianne Hackborn723738c2009-06-25 19:48:04 -07005338 // These semi-magic numbers define our compatibility modes for
5339 // applications with different screens. Don't change unless you
5340 // make sure to test lots and lots of apps!
5341 if (longSize < 470) {
5342 // This is shorter than an HVGA normal density screen (which
5343 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005344 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5345 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005346 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005347 // What size is this screen screen?
5348 if (longSize >= 800 && shortSize >= 600) {
5349 // SVGA or larger screens at medium density are the point
5350 // at which we consider it to be an extra large screen.
5351 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5352 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005353 // VGA or larger screens at medium density are the point
5354 // at which we consider it to be a large screen.
5355 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5356 } else {
5357 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005358
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005359 // If this screen is wider than normal HVGA, or taller
5360 // than FWVGA, then for old apps we want to run in size
5361 // compatibility mode.
5362 if (shortSize > 321 || longSize > 570) {
5363 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5364 }
5365 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005366
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005367 // Is this a long screen?
5368 if (((longSize*3)/5) >= (shortSize-1)) {
5369 // Anything wider than WVGA (5:3) is considering to be long.
5370 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5371 } else {
5372 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5373 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005374 }
5375 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005376 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005377
Dianne Hackbornc485a602009-03-24 22:39:49 -07005378 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5379 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5380 mPolicy.adjustConfigurationLw(config);
5381 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005383
5384 // -------------------------------------------------------------
5385 // Drag and drop
5386 // -------------------------------------------------------------
5387
5388 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
5389 boolean localOnly, int width, int height, Surface outSurface) {
5390 if (DEBUG_DRAG) {
5391 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
5392 + " local=" + localOnly + " win=" + window
5393 + " asbinder=" + window.asBinder());
5394 }
5395
5396 final int callerPid = Binder.getCallingPid();
5397 final long origId = Binder.clearCallingIdentity();
5398 IBinder token = null;
5399
5400 try {
5401 synchronized (mWindowMap) {
5402 try {
5403 // !!! TODO: fail if the given window does not currently have touch focus?
5404
5405 if (mDragState == null) {
5406 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5407 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5408 outSurface.copyFrom(surface);
5409 token = new Binder();
5410 mDragState = new DragState(token, surface, localOnly);
5411 mDragState.mSurface = surface;
5412 mDragState.mLocalOnly = localOnly;
5413 token = mDragState.mToken = new Binder();
5414
5415 // 5 second timeout for this window to actually begin the drag
5416 mH.removeMessages(H.DRAG_START_TIMEOUT, window);
5417 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, window.asBinder());
5418 mH.sendMessageDelayed(msg, 5000);
5419 } else {
5420 Slog.w(TAG, "Drag already in progress");
5421 }
5422 } catch (Surface.OutOfResourcesException e) {
5423 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5424 if (mDragState != null) {
5425 mDragState.reset();
5426 mDragState = null;
5427 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005428 }
5429 }
5430 } finally {
5431 Binder.restoreCallingIdentity(origId);
5432 }
5433
5434 return token;
5435 }
5436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005437 // -------------------------------------------------------------
5438 // Input Events and Focus Management
5439 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005440
Jeff Brown349703e2010-06-22 01:27:15 -07005441 InputMonitor mInputMonitor = new InputMonitor();
5442
5443 /* Tracks the progress of input dispatch and ensures that input dispatch state
5444 * is kept in sync with changes in window focus, visibility, registration, and
5445 * other relevant Window Manager state transitions. */
5446 final class InputMonitor {
5447 // Current window with input focus for keys and other non-touch events. May be null.
5448 private WindowState mInputFocus;
5449
5450 // When true, prevents input dispatch from proceeding until set to false again.
5451 private boolean mInputDispatchFrozen;
5452
5453 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5454 private boolean mInputDispatchEnabled = true;
5455
5456 // Temporary list of windows information to provide to the input dispatcher.
5457 private InputWindowList mTempInputWindows = new InputWindowList();
5458
5459 // Temporary input application object to provide to the input dispatcher.
5460 private InputApplication mTempInputApplication = new InputApplication();
5461
5462 /* Notifies the window manager about a broken input channel.
5463 *
5464 * Called by the InputManager.
5465 */
5466 public void notifyInputChannelBroken(InputChannel inputChannel) {
5467 synchronized (mWindowMap) {
5468 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5469 if (windowState == null) {
5470 return; // irrelevant
5471 }
5472
5473 Slog.i(TAG, "WINDOW DIED " + windowState);
5474 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005475 }
5476 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005477
Jeff Brown519e0242010-09-15 15:18:56 -07005478 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005479 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005480 *
5481 * Called by the InputManager.
5482 */
Jeff Brown519e0242010-09-15 15:18:56 -07005483 public long notifyANR(Object token, InputChannel inputChannel) {
5484 AppWindowToken appWindowToken = null;
5485 if (inputChannel != null) {
5486 synchronized (mWindowMap) {
5487 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5488 if (windowState != null) {
5489 Slog.i(TAG, "Input event dispatching timed out sending to "
5490 + windowState.mAttrs.getTitle());
5491 appWindowToken = windowState.mAppToken;
5492 }
Jeff Brown349703e2010-06-22 01:27:15 -07005493 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005494 }
5495
Jeff Brown519e0242010-09-15 15:18:56 -07005496 if (appWindowToken == null && token != null) {
5497 appWindowToken = (AppWindowToken) token;
5498 Slog.i(TAG, "Input event dispatching timed out sending to application "
5499 + appWindowToken.stringName);
5500 }
Jeff Brown349703e2010-06-22 01:27:15 -07005501
Jeff Brown519e0242010-09-15 15:18:56 -07005502 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005503 try {
5504 // Notify the activity manager about the timeout and let it decide whether
5505 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005506 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005507 if (! abort) {
5508 // The activity manager declined to abort dispatching.
5509 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005510 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005511 }
Jeff Brown349703e2010-06-22 01:27:15 -07005512 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005513 }
5514 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005515 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005516 }
5517
Jeff Brown349703e2010-06-22 01:27:15 -07005518 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5519 synchronized (mWindowMap) {
5520 return getWindowStateForInputChannelLocked(inputChannel);
5521 }
5522 }
5523
5524 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5525 int windowCount = mWindows.size();
5526 for (int i = 0; i < windowCount; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005527 WindowState windowState = mWindows.get(i);
Jeff Brown349703e2010-06-22 01:27:15 -07005528 if (windowState.mInputChannel == inputChannel) {
5529 return windowState;
5530 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005531 }
5532
Jeff Brown349703e2010-06-22 01:27:15 -07005533 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005534 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005535
5536 private void addDragInputWindow(InputWindowList windowList) {
5537 final InputWindow inputWindow = windowList.add();
5538 inputWindow.inputChannel = mDragState.mServerChannel;
5539 inputWindow.name = "drag";
5540 inputWindow.layoutParamsFlags = 0;
5541 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5542 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5543 inputWindow.visible = true;
5544 inputWindow.canReceiveKeys = false;
5545 inputWindow.hasFocus = true;
5546 inputWindow.hasWallpaper = false;
5547 inputWindow.paused = false;
5548 inputWindow.layer = mPolicy.windowTypeToLayerLw(inputWindow.layoutParamsType)
5549 * TYPE_LAYER_MULTIPLIER
5550 + TYPE_LAYER_OFFSET;
5551 inputWindow.ownerPid = Process.myPid();
5552 inputWindow.ownerUid = Process.myUid();
5553
5554 // The drag window covers the entire display
5555 inputWindow.frameLeft = 0;
5556 inputWindow.frameTop = 0;
5557 inputWindow.frameRight = mDisplay.getWidth();
5558 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005559
Christopher Tatea53146c2010-09-07 11:57:52 -07005560 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5561 inputWindow.visibleFrameTop = inputWindow.frameTop;
5562 inputWindow.visibleFrameRight = inputWindow.frameRight;
5563 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5564
5565 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5566 inputWindow.touchableAreaTop = inputWindow.frameTop;
5567 inputWindow.touchableAreaRight = inputWindow.frameRight;
5568 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5569 }
5570
Jeff Brown349703e2010-06-22 01:27:15 -07005571 /* Updates the cached window information provided to the input dispatcher. */
5572 public void updateInputWindowsLw() {
5573 // Populate the input window list with information about all of the windows that
5574 // could potentially receive input.
5575 // As an optimization, we could try to prune the list of windows but this turns
5576 // out to be difficult because only the native code knows for sure which window
5577 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005578 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005579
5580 // If there's a drag in flight, provide a pseudowindow to catch drag input
5581 final boolean inDrag = (mDragState != null);
5582 if (inDrag) {
5583 if (DEBUG_DRAG) {
5584 Log.d(TAG, "Inserting drag window");
5585 }
5586 addDragInputWindow(mTempInputWindows);
5587 }
5588
Jeff Brown7fbdc842010-06-17 20:52:56 -07005589 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005590 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005591 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005592 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005593 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005594 continue;
5595 }
5596
Jeff Brown349703e2010-06-22 01:27:15 -07005597 final int flags = child.mAttrs.flags;
5598 final int type = child.mAttrs.type;
5599
5600 final boolean hasFocus = (child == mInputFocus);
5601 final boolean isVisible = child.isVisibleLw();
5602 final boolean hasWallpaper = (child == mWallpaperTarget)
5603 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005604
5605 // If there's a drag in progress and 'child' is a potential drop target,
5606 // make sure it's been told about the drag
5607 if (inDrag && isVisible) {
5608 mDragState.sendDragStartedIfNeededLw(child);
5609 }
5610
Jeff Brown349703e2010-06-22 01:27:15 -07005611 // Add a window to our list of input windows.
5612 final InputWindow inputWindow = mTempInputWindows.add();
5613 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005614 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005615 inputWindow.layoutParamsFlags = flags;
5616 inputWindow.layoutParamsType = type;
5617 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5618 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005619 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005620 inputWindow.hasFocus = hasFocus;
5621 inputWindow.hasWallpaper = hasWallpaper;
5622 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005623 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005624 inputWindow.ownerPid = child.mSession.mPid;
5625 inputWindow.ownerUid = child.mSession.mUid;
5626
5627 final Rect frame = child.mFrame;
5628 inputWindow.frameLeft = frame.left;
5629 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005630 inputWindow.frameRight = frame.right;
5631 inputWindow.frameBottom = frame.bottom;
5632
5633 final Rect visibleFrame = child.mVisibleFrame;
5634 inputWindow.visibleFrameLeft = visibleFrame.left;
5635 inputWindow.visibleFrameTop = visibleFrame.top;
5636 inputWindow.visibleFrameRight = visibleFrame.right;
5637 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005638
5639 switch (child.mTouchableInsets) {
5640 default:
5641 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5642 inputWindow.touchableAreaLeft = frame.left;
5643 inputWindow.touchableAreaTop = frame.top;
5644 inputWindow.touchableAreaRight = frame.right;
5645 inputWindow.touchableAreaBottom = frame.bottom;
5646 break;
5647
5648 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5649 Rect inset = child.mGivenContentInsets;
5650 inputWindow.touchableAreaLeft = frame.left + inset.left;
5651 inputWindow.touchableAreaTop = frame.top + inset.top;
5652 inputWindow.touchableAreaRight = frame.right - inset.right;
5653 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5654 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005655 }
Jeff Brown349703e2010-06-22 01:27:15 -07005656
5657 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5658 Rect inset = child.mGivenVisibleInsets;
5659 inputWindow.touchableAreaLeft = frame.left + inset.left;
5660 inputWindow.touchableAreaTop = frame.top + inset.top;
5661 inputWindow.touchableAreaRight = frame.right - inset.right;
5662 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005663 break;
5664 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005665 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005666 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005667
Jeff Brown349703e2010-06-22 01:27:15 -07005668 // Send windows to native code.
5669 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005670
Jeff Brown349703e2010-06-22 01:27:15 -07005671 // Clear the list in preparation for the next round.
5672 // Also avoids keeping InputChannel objects referenced unnecessarily.
5673 mTempInputWindows.clear();
5674 }
5675
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005676 /* Notifies that the lid switch changed state. */
5677 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5678 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5679 }
5680
Jeff Brown349703e2010-06-22 01:27:15 -07005681 /* Provides an opportunity for the window manager policy to intercept early key
5682 * processing as soon as the key has been read from the device. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005683 public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
5684 int policyFlags, boolean isScreenOn) {
5685 return mPolicy.interceptKeyBeforeQueueing(whenNanos,
5686 keyCode, down, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005687 }
5688
5689 /* Provides an opportunity for the window manager policy to process a key before
5690 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005691 public boolean interceptKeyBeforeDispatching(InputChannel focus,
5692 int action, int flags, int keyCode, int metaState, int repeatCount,
5693 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005694 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005695 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
5696 keyCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005697 }
5698
5699 /* Called when the current input focus changes.
5700 * Layer assignment is assumed to be complete by the time this is called.
5701 */
5702 public void setInputFocusLw(WindowState newWindow) {
5703 if (DEBUG_INPUT) {
5704 Slog.d(TAG, "Input focus has changed to " + newWindow);
5705 }
5706
5707 if (newWindow != mInputFocus) {
5708 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005709 // Displaying a window implicitly causes dispatching to be unpaused.
5710 // This is to protect against bugs if someone pauses dispatching but
5711 // forgets to resume.
5712 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005713 }
Jeff Brown349703e2010-06-22 01:27:15 -07005714
5715 mInputFocus = newWindow;
5716 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005717 }
5718 }
5719
Jeff Brown349703e2010-06-22 01:27:15 -07005720 public void setFocusedAppLw(AppWindowToken newApp) {
5721 // Focused app has changed.
5722 if (newApp == null) {
5723 mInputManager.setFocusedApplication(null);
5724 } else {
5725 mTempInputApplication.name = newApp.toString();
5726 mTempInputApplication.dispatchingTimeoutNanos =
5727 newApp.inputDispatchingTimeoutNanos;
5728 mTempInputApplication.token = newApp;
5729
5730 mInputManager.setFocusedApplication(mTempInputApplication);
5731 }
5732 }
5733
Jeff Brown349703e2010-06-22 01:27:15 -07005734 public void pauseDispatchingLw(WindowToken window) {
5735 if (! window.paused) {
5736 if (DEBUG_INPUT) {
5737 Slog.v(TAG, "Pausing WindowToken " + window);
5738 }
5739
5740 window.paused = true;
5741 updateInputWindowsLw();
5742 }
5743 }
5744
5745 public void resumeDispatchingLw(WindowToken window) {
5746 if (window.paused) {
5747 if (DEBUG_INPUT) {
5748 Slog.v(TAG, "Resuming WindowToken " + window);
5749 }
5750
5751 window.paused = false;
5752 updateInputWindowsLw();
5753 }
5754 }
5755
5756 public void freezeInputDispatchingLw() {
5757 if (! mInputDispatchFrozen) {
5758 if (DEBUG_INPUT) {
5759 Slog.v(TAG, "Freezing input dispatching");
5760 }
5761
5762 mInputDispatchFrozen = true;
5763 updateInputDispatchModeLw();
5764 }
5765 }
5766
5767 public void thawInputDispatchingLw() {
5768 if (mInputDispatchFrozen) {
5769 if (DEBUG_INPUT) {
5770 Slog.v(TAG, "Thawing input dispatching");
5771 }
5772
5773 mInputDispatchFrozen = false;
5774 updateInputDispatchModeLw();
5775 }
5776 }
5777
5778 public void setEventDispatchingLw(boolean enabled) {
5779 if (mInputDispatchEnabled != enabled) {
5780 if (DEBUG_INPUT) {
5781 Slog.v(TAG, "Setting event dispatching to " + enabled);
5782 }
5783
5784 mInputDispatchEnabled = enabled;
5785 updateInputDispatchModeLw();
5786 }
5787 }
5788
5789 private void updateInputDispatchModeLw() {
5790 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5791 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 public void pauseKeyDispatching(IBinder _token) {
5795 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5796 "pauseKeyDispatching()")) {
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.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 }
5805 }
5806 }
5807
5808 public void resumeKeyDispatching(IBinder _token) {
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) {
5815 WindowToken token = mTokenMap.get(_token);
5816 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005817 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 }
5819 }
5820 }
5821
5822 public void setEventDispatching(boolean enabled) {
5823 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5824 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005825 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005826 }
5827
5828 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005829 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 }
5831 }
Romain Guy06882f82009-06-10 13:36:04 -07005832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 /**
5834 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005835 * Even when sync is false, this method may block while waiting for current
5836 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005837 *
5838 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 * {@link SystemClock#uptimeMillis()} as the timebase.)
5840 * @param sync If true, wait for the event to be completed before returning to the caller.
5841 * @return Returns true if event was dispatched, false if it was dropped for any reason
5842 */
5843 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5844 long downTime = ev.getDownTime();
5845 long eventTime = ev.getEventTime();
5846
5847 int action = ev.getAction();
5848 int code = ev.getKeyCode();
5849 int repeatCount = ev.getRepeatCount();
5850 int metaState = ev.getMetaState();
5851 int deviceId = ev.getDeviceId();
5852 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005853 int source = ev.getSource();
5854
5855 if (source == InputDevice.SOURCE_UNKNOWN) {
5856 source = InputDevice.SOURCE_KEYBOARD;
5857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005858
5859 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5860 if (downTime == 0) downTime = eventTime;
5861
5862 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jeff Brownc5ed5912010-07-14 18:48:53 -07005863 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005864
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005865 final int pid = Binder.getCallingPid();
5866 final int uid = Binder.getCallingUid();
5867 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005868
Jeff Brownbbda99d2010-07-28 15:48:59 -07005869 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5870 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5871 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5872 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005873
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005874 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005875 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876 }
5877
5878 /**
5879 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005880 * Even when sync is false, this method may block while waiting for current
5881 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005882 *
5883 * @param ev A motion event describing the pointer (touch) action. (As noted in
5884 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 * {@link SystemClock#uptimeMillis()} as the timebase.)
5886 * @param sync If true, wait for the event to be completed before returning to the caller.
5887 * @return Returns true if event was dispatched, false if it was dropped for any reason
5888 */
5889 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005890 final int pid = Binder.getCallingPid();
5891 final int uid = Binder.getCallingUid();
5892 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005893
Jeff Brownc5ed5912010-07-14 18:48:53 -07005894 MotionEvent newEvent = MotionEvent.obtain(ev);
5895 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5896 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5897 }
5898
Jeff Brownbbda99d2010-07-28 15:48:59 -07005899 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5900 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5901 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5902 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005903
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005904 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005905 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005906 }
Romain Guy06882f82009-06-10 13:36:04 -07005907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 /**
5909 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005910 * Even when sync is false, this method may block while waiting for current
5911 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005912 *
5913 * @param ev A motion event describing the trackball action. (As noted in
5914 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 * {@link SystemClock#uptimeMillis()} as the timebase.)
5916 * @param sync If true, wait for the event to be completed before returning to the caller.
5917 * @return Returns true if event was dispatched, false if it was dropped for any reason
5918 */
5919 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005920 final int pid = Binder.getCallingPid();
5921 final int uid = Binder.getCallingUid();
5922 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005923
Jeff Brownc5ed5912010-07-14 18:48:53 -07005924 MotionEvent newEvent = MotionEvent.obtain(ev);
5925 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5926 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5927 }
5928
Jeff Brownbbda99d2010-07-28 15:48:59 -07005929 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5930 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5931 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5932 INJECTION_TIMEOUT_MILLIS);
5933
5934 Binder.restoreCallingIdentity(ident);
5935 return reportInjectionResult(result);
5936 }
5937
5938 /**
5939 * Inject an input event into the UI without waiting for dispatch to commence.
5940 * This variant is useful for fire-and-forget input event injection. It does not
5941 * block any longer than it takes to enqueue the input event.
5942 *
5943 * @param ev An input event. (Be sure to set the input source correctly.)
5944 * @return Returns true if event was dispatched, false if it was dropped for any reason
5945 */
5946 public boolean injectInputEventNoWait(InputEvent ev) {
5947 final int pid = Binder.getCallingPid();
5948 final int uid = Binder.getCallingUid();
5949 final long ident = Binder.clearCallingIdentity();
5950
5951 final int result = mInputManager.injectInputEvent(ev, pid, uid,
5952 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
5953 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005954
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005955 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005956 return reportInjectionResult(result);
5957 }
5958
5959 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005960 switch (result) {
5961 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5962 Slog.w(TAG, "Input event injection permission denied.");
5963 throw new SecurityException(
5964 "Injecting to another application requires INJECT_EVENTS permission");
5965 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07005966 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005967 return true;
5968 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5969 Slog.w(TAG, "Input event injection timed out.");
5970 return false;
5971 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5972 default:
5973 Slog.w(TAG, "Input event injection failed.");
5974 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005976 }
Romain Guy06882f82009-06-10 13:36:04 -07005977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 private WindowState getFocusedWindow() {
5979 synchronized (mWindowMap) {
5980 return getFocusedWindowLocked();
5981 }
5982 }
5983
5984 private WindowState getFocusedWindowLocked() {
5985 return mCurrentFocus;
5986 }
Romain Guy06882f82009-06-10 13:36:04 -07005987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988 public boolean detectSafeMode() {
5989 mSafeMode = mPolicy.detectSafeMode();
5990 return mSafeMode;
5991 }
Romain Guy06882f82009-06-10 13:36:04 -07005992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07005994 synchronized(mWindowMap) {
5995 if (mDisplay != null) {
5996 throw new IllegalStateException("Display already initialized");
5997 }
5998 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
5999 mDisplay = wm.getDefaultDisplay();
6000 mInitialDisplayWidth = mDisplay.getWidth();
6001 mInitialDisplayHeight = mDisplay.getHeight();
6002 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
6003 }
6004
6005 try {
6006 mActivityManager.updateConfiguration(null);
6007 } catch (RemoteException e) {
6008 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006009
6010 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006011 }
6012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013 // -------------------------------------------------------------
6014 // Client Session State
6015 // -------------------------------------------------------------
6016
6017 private final class Session extends IWindowSession.Stub
6018 implements IBinder.DeathRecipient {
6019 final IInputMethodClient mClient;
6020 final IInputContext mInputContext;
6021 final int mUid;
6022 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006023 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006024 SurfaceSession mSurfaceSession;
6025 int mNumWindow = 0;
6026 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006028 public Session(IInputMethodClient client, IInputContext inputContext) {
6029 mClient = client;
6030 mInputContext = inputContext;
6031 mUid = Binder.getCallingUid();
6032 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006033 StringBuilder sb = new StringBuilder();
6034 sb.append("Session{");
6035 sb.append(Integer.toHexString(System.identityHashCode(this)));
6036 sb.append(" uid ");
6037 sb.append(mUid);
6038 sb.append("}");
6039 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 synchronized (mWindowMap) {
6042 if (mInputMethodManager == null && mHaveInputMethods) {
6043 IBinder b = ServiceManager.getService(
6044 Context.INPUT_METHOD_SERVICE);
6045 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6046 }
6047 }
6048 long ident = Binder.clearCallingIdentity();
6049 try {
6050 // Note: it is safe to call in to the input method manager
6051 // here because we are not holding our lock.
6052 if (mInputMethodManager != null) {
6053 mInputMethodManager.addClient(client, inputContext,
6054 mUid, mPid);
6055 } else {
6056 client.setUsingInputMethod(false);
6057 }
6058 client.asBinder().linkToDeath(this, 0);
6059 } catch (RemoteException e) {
6060 // The caller has died, so we can just forget about this.
6061 try {
6062 if (mInputMethodManager != null) {
6063 mInputMethodManager.removeClient(client);
6064 }
6065 } catch (RemoteException ee) {
6066 }
6067 } finally {
6068 Binder.restoreCallingIdentity(ident);
6069 }
6070 }
Romain Guy06882f82009-06-10 13:36:04 -07006071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006072 @Override
6073 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6074 throws RemoteException {
6075 try {
6076 return super.onTransact(code, data, reply, flags);
6077 } catch (RuntimeException e) {
6078 // Log all 'real' exceptions thrown to the caller
6079 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006080 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 }
6082 throw e;
6083 }
6084 }
6085
6086 public void binderDied() {
6087 // Note: it is safe to call in to the input method manager
6088 // here because we are not holding our lock.
6089 try {
6090 if (mInputMethodManager != null) {
6091 mInputMethodManager.removeClient(mClient);
6092 }
6093 } catch (RemoteException e) {
6094 }
6095 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006096 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 mClientDead = true;
6098 killSessionLocked();
6099 }
6100 }
6101
6102 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006103 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6104 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6105 outInputChannel);
6106 }
6107
6108 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006110 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 }
Romain Guy06882f82009-06-10 13:36:04 -07006112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 public void remove(IWindow window) {
6114 removeWindow(this, window);
6115 }
Romain Guy06882f82009-06-10 13:36:04 -07006116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6118 int requestedWidth, int requestedHeight, int viewFlags,
6119 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006120 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006121 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6122 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006123 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006124 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006125 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6126 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006127 }
Romain Guy06882f82009-06-10 13:36:04 -07006128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 public void setTransparentRegion(IWindow window, Region region) {
6130 setTransparentRegionWindow(this, window, region);
6131 }
Romain Guy06882f82009-06-10 13:36:04 -07006132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 public void setInsets(IWindow window, int touchableInsets,
6134 Rect contentInsets, Rect visibleInsets) {
6135 setInsetsWindow(this, window, touchableInsets, contentInsets,
6136 visibleInsets);
6137 }
Romain Guy06882f82009-06-10 13:36:04 -07006138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6140 getWindowDisplayFrame(this, window, outDisplayFrame);
6141 }
Romain Guy06882f82009-06-10 13:36:04 -07006142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006143 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006144 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 TAG, "IWindow finishDrawing called for " + window);
6146 finishDrawingWindow(this, window);
6147 }
6148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006149 public void setInTouchMode(boolean mode) {
6150 synchronized(mWindowMap) {
6151 mInTouchMode = mode;
6152 }
6153 }
6154
6155 public boolean getInTouchMode() {
6156 synchronized(mWindowMap) {
6157 return mInTouchMode;
6158 }
6159 }
6160
6161 public boolean performHapticFeedback(IWindow window, int effectId,
6162 boolean always) {
6163 synchronized(mWindowMap) {
6164 long ident = Binder.clearCallingIdentity();
6165 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006166 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006167 windowForClientLocked(this, window, true),
6168 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 } finally {
6170 Binder.restoreCallingIdentity(ident);
6171 }
6172 }
6173 }
Romain Guy06882f82009-06-10 13:36:04 -07006174
Christopher Tatea53146c2010-09-07 11:57:52 -07006175 /* Drag/drop */
6176 public IBinder prepareDrag(IWindow window, boolean localOnly,
6177 int width, int height, Surface outSurface) {
6178 return prepareDragSurface(window, mSurfaceSession, localOnly,
6179 width, height, outSurface);
6180 }
6181
6182 public boolean performDrag(IWindow window, IBinder dragToken,
6183 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6184 ClipData data) {
6185 if (DEBUG_DRAG) {
6186 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6187 }
6188
6189 synchronized (mWindowMap) {
6190 if (mDragState == null) {
6191 Slog.w(TAG, "No drag prepared");
6192 throw new IllegalStateException("performDrag() without prepareDrag()");
6193 }
6194
6195 if (dragToken != mDragState.mToken) {
6196 Slog.w(TAG, "Performing mismatched drag");
6197 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6198 }
6199
6200 WindowState callingWin = windowForClientLocked(null, window, false);
6201 if (callingWin == null) {
6202 Slog.w(TAG, "Bad requesting window " + window);
6203 return false; // !!! TODO: throw here?
6204 }
6205
6206 // !!! TODO: if input is not still focused on the initiating window, fail
6207 // the drag initiation (e.g. an alarm window popped up just as the application
6208 // called performDrag()
6209
6210 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6211
Christopher Tate2c095f32010-10-04 14:13:40 -07006212 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6213 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006214
6215 mDragState.register();
6216 mInputMonitor.updateInputWindowsLw();
6217 mInputManager.transferTouchFocus(callingWin.mInputChannel,
6218 mDragState.mServerChannel);
6219
6220 mDragState.mData = data;
Chris Tateb8203e92010-10-12 14:23:21 -07006221 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006222
6223 // remember the thumb offsets for later
6224 mDragState.mThumbOffsetX = thumbCenterX;
6225 mDragState.mThumbOffsetY = thumbCenterY;
6226
6227 // Make the surface visible at the proper location
6228 final Surface surface = mDragState.mSurface;
6229 surface.openTransaction();
6230 try {
6231 surface.setPosition((int)(touchX - thumbCenterX),
6232 (int)(touchY - thumbCenterY));
6233 surface.setAlpha(.5f);
6234 surface.show();
6235 } finally {
6236 surface.closeTransaction();
6237 }
6238 }
6239
6240 return true; // success!
6241 }
6242
6243 public void dragRecipientEntered(IWindow window) {
6244 if (DEBUG_DRAG) {
6245 Slog.d(TAG, "Drag into new candidate view @ " + window);
6246 }
6247 }
6248
6249 public void dragRecipientExited(IWindow window) {
6250 if (DEBUG_DRAG) {
6251 Slog.d(TAG, "Drag from old candidate view @ " + window);
6252 }
6253 }
6254
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006255 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006256 synchronized(mWindowMap) {
6257 long ident = Binder.clearCallingIdentity();
6258 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006259 setWindowWallpaperPositionLocked(
6260 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006261 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006262 } finally {
6263 Binder.restoreCallingIdentity(ident);
6264 }
6265 }
6266 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006267
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006268 public void wallpaperOffsetsComplete(IBinder window) {
6269 WindowManagerService.this.wallpaperOffsetsComplete(window);
6270 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006271
Dianne Hackborn75804932009-10-20 20:15:20 -07006272 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6273 int z, Bundle extras, boolean sync) {
6274 synchronized(mWindowMap) {
6275 long ident = Binder.clearCallingIdentity();
6276 try {
6277 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006278 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006279 action, x, y, z, extras, sync);
6280 } finally {
6281 Binder.restoreCallingIdentity(ident);
6282 }
6283 }
6284 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006285
Dianne Hackborn75804932009-10-20 20:15:20 -07006286 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6287 WindowManagerService.this.wallpaperCommandComplete(window, result);
6288 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 void windowAddedLocked() {
6291 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006292 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006293 TAG, "First window added to " + this + ", creating SurfaceSession");
6294 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006295 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006296 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 mSessions.add(this);
6298 }
6299 mNumWindow++;
6300 }
6301
6302 void windowRemovedLocked() {
6303 mNumWindow--;
6304 killSessionLocked();
6305 }
Romain Guy06882f82009-06-10 13:36:04 -07006306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 void killSessionLocked() {
6308 if (mNumWindow <= 0 && mClientDead) {
6309 mSessions.remove(this);
6310 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006311 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 TAG, "Last window removed from " + this
6313 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006314 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006315 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 try {
6317 mSurfaceSession.kill();
6318 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006319 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 + mSurfaceSession + " in session " + this
6321 + ": " + e.toString());
6322 }
6323 mSurfaceSession = null;
6324 }
6325 }
6326 }
Romain Guy06882f82009-06-10 13:36:04 -07006327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006328 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006329 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6330 pw.print(" mClientDead="); pw.print(mClientDead);
6331 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 }
6333
6334 @Override
6335 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006336 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 }
6338 }
6339
6340 // -------------------------------------------------------------
6341 // Client Window State
6342 // -------------------------------------------------------------
6343
6344 private final class WindowState implements WindowManagerPolicy.WindowState {
6345 final Session mSession;
6346 final IWindow mClient;
6347 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006348 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 AppWindowToken mAppToken;
6350 AppWindowToken mTargetAppToken;
6351 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6352 final DeathRecipient mDeathRecipient;
6353 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006354 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 final int mBaseLayer;
6356 final int mSubLayer;
6357 final boolean mLayoutAttached;
6358 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006359 final boolean mIsWallpaper;
6360 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361 int mViewVisibility;
6362 boolean mPolicyVisibility = true;
6363 boolean mPolicyVisibilityAfterAnim = true;
6364 boolean mAppFreezing;
6365 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006366 boolean mReportDestroySurface;
6367 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368 boolean mAttachedHidden; // is our parent window hidden?
6369 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006370 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006371 int mRequestedWidth;
6372 int mRequestedHeight;
6373 int mLastRequestedWidth;
6374 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006375 int mLayer;
6376 int mAnimLayer;
6377 int mLastLayer;
6378 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006379 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006380 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006382 int mLayoutSeq = -1;
6383
6384 Configuration mConfiguration = null;
6385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 // Actual frame shown on-screen (may be modified by animation)
6387 final Rect mShownFrame = new Rect();
6388 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006391 * Set when we have changed the size of the surface, to know that
6392 * we must tell them application to resize (and thus redraw itself).
6393 */
6394 boolean mSurfaceResized;
6395
6396 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006397 * Insets that determine the actually visible area
6398 */
6399 final Rect mVisibleInsets = new Rect();
6400 final Rect mLastVisibleInsets = new Rect();
6401 boolean mVisibleInsetsChanged;
6402
6403 /**
6404 * Insets that are covered by system windows
6405 */
6406 final Rect mContentInsets = new Rect();
6407 final Rect mLastContentInsets = new Rect();
6408 boolean mContentInsetsChanged;
6409
6410 /**
6411 * Set to true if we are waiting for this window to receive its
6412 * given internal insets before laying out other windows based on it.
6413 */
6414 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006416 /**
6417 * These are the content insets that were given during layout for
6418 * this window, to be applied to windows behind it.
6419 */
6420 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006422 /**
6423 * These are the visible insets that were given during layout for
6424 * this window, to be applied to windows behind it.
6425 */
6426 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 /**
6429 * Flag indicating whether the touchable region should be adjusted by
6430 * the visible insets; if false the area outside the visible insets is
6431 * NOT touchable, so we must use those to adjust the frame during hit
6432 * tests.
6433 */
6434 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006436 // Current transformation being applied.
6437 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6438 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6439 float mHScale=1, mVScale=1;
6440 float mLastHScale=1, mLastVScale=1;
6441 final Matrix mTmpMatrix = new Matrix();
6442
6443 // "Real" frame that the application sees.
6444 final Rect mFrame = new Rect();
6445 final Rect mLastFrame = new Rect();
6446
6447 final Rect mContainingFrame = new Rect();
6448 final Rect mDisplayFrame = new Rect();
6449 final Rect mContentFrame = new Rect();
6450 final Rect mVisibleFrame = new Rect();
6451
6452 float mShownAlpha = 1;
6453 float mAlpha = 1;
6454 float mLastAlpha = 1;
6455
6456 // Set to true if, when the window gets displayed, it should perform
6457 // an enter animation.
6458 boolean mEnterAnimationPending;
6459
6460 // Currently running animation.
6461 boolean mAnimating;
6462 boolean mLocalAnimating;
6463 Animation mAnimation;
6464 boolean mAnimationIsEntrance;
6465 boolean mHasTransformation;
6466 boolean mHasLocalTransformation;
6467 final Transformation mTransformation = new Transformation();
6468
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006469 // If a window showing a wallpaper: the requested offset for the
6470 // wallpaper; if a wallpaper window: the currently applied offset.
6471 float mWallpaperX = -1;
6472 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006473
6474 // If a window showing a wallpaper: what fraction of the offset
6475 // range corresponds to a full virtual screen.
6476 float mWallpaperXStep = -1;
6477 float mWallpaperYStep = -1;
6478
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006479 // Wallpaper windows: pixels offset based on above variables.
6480 int mXOffset;
6481 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006483 // This is set after IWindowSession.relayout() has been called at
6484 // least once for the window. It allows us to detect the situation
6485 // where we don't yet have a surface, but should have one soon, so
6486 // we can give the window focus before waiting for the relayout.
6487 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006489 // This is set after the Surface has been created but before the
6490 // window has been drawn. During this time the surface is hidden.
6491 boolean mDrawPending;
6492
6493 // This is set after the window has finished drawing for the first
6494 // time but before its surface is shown. The surface will be
6495 // displayed when the next layout is run.
6496 boolean mCommitDrawPending;
6497
6498 // This is set during the time after the window's drawing has been
6499 // committed, and before its surface is actually shown. It is used
6500 // to delay showing the surface until all windows in a token are ready
6501 // to be shown.
6502 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006504 // Set when the window has been shown in the screen the first time.
6505 boolean mHasDrawn;
6506
6507 // Currently running an exit animation?
6508 boolean mExiting;
6509
6510 // Currently on the mDestroySurface list?
6511 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 // Completely remove from window manager after exit animation?
6514 boolean mRemoveOnExit;
6515
6516 // Set when the orientation is changing and this window has not yet
6517 // been updated for the new orientation.
6518 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006520 // Is this window now (or just being) removed?
6521 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006522
Dianne Hackborn16064f92010-03-25 00:47:24 -07006523 // For debugging, this is the last information given to the surface flinger.
6524 boolean mSurfaceShown;
6525 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6526 int mSurfaceLayer;
6527 float mSurfaceAlpha;
6528
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006529 // Input channel
6530 InputChannel mInputChannel;
6531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 WindowState(Session s, IWindow c, WindowToken token,
6533 WindowState attachedWindow, WindowManager.LayoutParams a,
6534 int viewVisibility) {
6535 mSession = s;
6536 mClient = c;
6537 mToken = token;
6538 mAttrs.copyFrom(a);
6539 mViewVisibility = viewVisibility;
6540 DeathRecipient deathRecipient = new DeathRecipient();
6541 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006542 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006543 TAG, "Window " + this + " client=" + c.asBinder()
6544 + " token=" + token + " (" + mAttrs.token + ")");
6545 try {
6546 c.asBinder().linkToDeath(deathRecipient, 0);
6547 } catch (RemoteException e) {
6548 mDeathRecipient = null;
6549 mAttachedWindow = null;
6550 mLayoutAttached = false;
6551 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006552 mIsWallpaper = false;
6553 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006554 mBaseLayer = 0;
6555 mSubLayer = 0;
6556 return;
6557 }
6558 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6561 mAttrs.type <= LAST_SUB_WINDOW)) {
6562 // The multiplier here is to reserve space for multiple
6563 // windows in the same type layer.
6564 mBaseLayer = mPolicy.windowTypeToLayerLw(
6565 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6566 + TYPE_LAYER_OFFSET;
6567 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6568 mAttachedWindow = attachedWindow;
6569 mAttachedWindow.mChildWindows.add(this);
6570 mLayoutAttached = mAttrs.type !=
6571 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6572 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6573 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006574 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6575 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006576 } else {
6577 // The multiplier here is to reserve space for multiple
6578 // windows in the same type layer.
6579 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6580 * TYPE_LAYER_MULTIPLIER
6581 + TYPE_LAYER_OFFSET;
6582 mSubLayer = 0;
6583 mAttachedWindow = null;
6584 mLayoutAttached = false;
6585 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6586 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006587 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6588 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006589 }
6590
6591 WindowState appWin = this;
6592 while (appWin.mAttachedWindow != null) {
6593 appWin = mAttachedWindow;
6594 }
6595 WindowToken appToken = appWin.mToken;
6596 while (appToken.appWindowToken == null) {
6597 WindowToken parent = mTokenMap.get(appToken.token);
6598 if (parent == null || appToken == parent) {
6599 break;
6600 }
6601 appToken = parent;
6602 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006603 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 mAppToken = appToken.appWindowToken;
6605
6606 mSurface = null;
6607 mRequestedWidth = 0;
6608 mRequestedHeight = 0;
6609 mLastRequestedWidth = 0;
6610 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006611 mXOffset = 0;
6612 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 mLayer = 0;
6614 mAnimLayer = 0;
6615 mLastLayer = 0;
6616 }
6617
6618 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006619 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 TAG, "Attaching " + this + " token=" + mToken
6621 + ", list=" + mToken.windows);
6622 mSession.windowAddedLocked();
6623 }
6624
6625 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6626 mHaveFrame = true;
6627
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006628 final Rect container = mContainingFrame;
6629 container.set(pf);
6630
6631 final Rect display = mDisplayFrame;
6632 display.set(df);
6633
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006634 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006635 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006636 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6637 display.intersect(mCompatibleScreenFrame);
6638 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006639 }
6640
6641 final int pw = container.right - container.left;
6642 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006643
6644 int w,h;
6645 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6646 w = mAttrs.width < 0 ? pw : mAttrs.width;
6647 h = mAttrs.height< 0 ? ph : mAttrs.height;
6648 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006649 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6650 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 }
Romain Guy06882f82009-06-10 13:36:04 -07006652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 final Rect content = mContentFrame;
6654 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 final Rect visible = mVisibleFrame;
6657 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006660 final int fw = frame.width();
6661 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6664 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6665
6666 Gravity.apply(mAttrs.gravity, w, h, container,
6667 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6668 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6669
6670 //System.out.println("Out: " + mFrame);
6671
6672 // Now make sure the window fits in the overall display.
6673 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 // Make sure the content and visible frames are inside of the
6676 // final window frame.
6677 if (content.left < frame.left) content.left = frame.left;
6678 if (content.top < frame.top) content.top = frame.top;
6679 if (content.right > frame.right) content.right = frame.right;
6680 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6681 if (visible.left < frame.left) visible.left = frame.left;
6682 if (visible.top < frame.top) visible.top = frame.top;
6683 if (visible.right > frame.right) visible.right = frame.right;
6684 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 final Rect contentInsets = mContentInsets;
6687 contentInsets.left = content.left-frame.left;
6688 contentInsets.top = content.top-frame.top;
6689 contentInsets.right = frame.right-content.right;
6690 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 final Rect visibleInsets = mVisibleInsets;
6693 visibleInsets.left = visible.left-frame.left;
6694 visibleInsets.top = visible.top-frame.top;
6695 visibleInsets.right = frame.right-visible.right;
6696 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006697
Dianne Hackborn284ac932009-08-28 10:34:25 -07006698 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6699 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006700 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006701 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 if (localLOGV) {
6704 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6705 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006706 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 + mRequestedWidth + ", mRequestedheight="
6708 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6709 + "): frame=" + mFrame.toShortString()
6710 + " ci=" + contentInsets.toShortString()
6711 + " vi=" + visibleInsets.toShortString());
6712 //}
6713 }
6714 }
Romain Guy06882f82009-06-10 13:36:04 -07006715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 public Rect getFrameLw() {
6717 return mFrame;
6718 }
6719
6720 public Rect getShownFrameLw() {
6721 return mShownFrame;
6722 }
6723
6724 public Rect getDisplayFrameLw() {
6725 return mDisplayFrame;
6726 }
6727
6728 public Rect getContentFrameLw() {
6729 return mContentFrame;
6730 }
6731
6732 public Rect getVisibleFrameLw() {
6733 return mVisibleFrame;
6734 }
6735
6736 public boolean getGivenInsetsPendingLw() {
6737 return mGivenInsetsPending;
6738 }
6739
6740 public Rect getGivenContentInsetsLw() {
6741 return mGivenContentInsets;
6742 }
Romain Guy06882f82009-06-10 13:36:04 -07006743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 public Rect getGivenVisibleInsetsLw() {
6745 return mGivenVisibleInsets;
6746 }
Romain Guy06882f82009-06-10 13:36:04 -07006747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006748 public WindowManager.LayoutParams getAttrs() {
6749 return mAttrs;
6750 }
6751
6752 public int getSurfaceLayer() {
6753 return mLayer;
6754 }
Romain Guy06882f82009-06-10 13:36:04 -07006755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756 public IApplicationToken getAppToken() {
6757 return mAppToken != null ? mAppToken.appToken : null;
6758 }
Jeff Brown349703e2010-06-22 01:27:15 -07006759
6760 public long getInputDispatchingTimeoutNanos() {
6761 return mAppToken != null
6762 ? mAppToken.inputDispatchingTimeoutNanos
6763 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765
6766 public boolean hasAppShownWindows() {
6767 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6768 }
6769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006770 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006771 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 TAG, "Setting animation in " + this + ": " + anim);
6773 mAnimating = false;
6774 mLocalAnimating = false;
6775 mAnimation = anim;
6776 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6777 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6778 }
6779
6780 public void clearAnimation() {
6781 if (mAnimation != null) {
6782 mAnimating = true;
6783 mLocalAnimating = false;
6784 mAnimation = null;
6785 }
6786 }
Romain Guy06882f82009-06-10 13:36:04 -07006787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 Surface createSurfaceLocked() {
6789 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006790 mReportDestroySurface = false;
6791 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 mDrawPending = true;
6793 mCommitDrawPending = false;
6794 mReadyToShow = false;
6795 if (mAppToken != null) {
6796 mAppToken.allDrawn = false;
6797 }
6798
6799 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006800 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 flags |= Surface.PUSH_BUFFERS;
6802 }
6803
6804 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6805 flags |= Surface.SECURE;
6806 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006807 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 TAG, "Creating surface in session "
6809 + mSession.mSurfaceSession + " window " + this
6810 + " w=" + mFrame.width()
6811 + " h=" + mFrame.height() + " format="
6812 + mAttrs.format + " flags=" + flags);
6813
6814 int w = mFrame.width();
6815 int h = mFrame.height();
6816 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
6817 // for a scaled surface, we always want the requested
6818 // size.
6819 w = mRequestedWidth;
6820 h = mRequestedHeight;
6821 }
6822
Romain Guy9825ec62009-10-01 00:58:09 -07006823 // Something is wrong and SurfaceFlinger will not like this,
6824 // try to revert to sane values
6825 if (w <= 0) w = 1;
6826 if (h <= 0) h = 1;
6827
Dianne Hackborn16064f92010-03-25 00:47:24 -07006828 mSurfaceShown = false;
6829 mSurfaceLayer = 0;
6830 mSurfaceAlpha = 1;
6831 mSurfaceX = 0;
6832 mSurfaceY = 0;
6833 mSurfaceW = w;
6834 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 try {
Romain Guyd10cd572010-10-10 13:33:22 -07006836 final boolean isHwAccelerated = (mAttrs.flags &
6837 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
6838 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
6839 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
6840 flags |= Surface.OPAQUE;
6841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07006843 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08006844 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07006845 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006846 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006847 + mSurface + " IN SESSION "
6848 + mSession.mSurfaceSession
6849 + ": pid=" + mSession.mPid + " format="
6850 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006851 + Integer.toHexString(flags)
6852 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006854 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 reclaimSomeSurfaceMemoryLocked(this, "create");
6856 return null;
6857 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006858 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006859 return null;
6860 }
Romain Guy06882f82009-06-10 13:36:04 -07006861
Joe Onorato8a9b2202010-02-26 18:56:32 -08006862 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 TAG, "Got surface: " + mSurface
6864 + ", set left=" + mFrame.left + " top=" + mFrame.top
6865 + ", animLayer=" + mAnimLayer);
6866 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006867 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006868 if (SHOW_TRANSACTIONS) logSurface(this,
6869 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
6870 mFrame.width() + "x" + mFrame.height() + "), layer=" +
6871 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 }
6873 Surface.openTransaction();
6874 try {
6875 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07006876 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07006877 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07006878 mSurface.setPosition(mSurfaceX, mSurfaceY);
6879 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006881 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 mSurface.hide();
6883 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006884 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 mSurface.setFlags(Surface.SURFACE_DITHER,
6886 Surface.SURFACE_DITHER);
6887 }
6888 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006889 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 reclaimSomeSurfaceMemoryLocked(this, "create-init");
6891 }
6892 mLastHidden = true;
6893 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006894 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 Surface.closeTransaction();
6896 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006897 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 TAG, "Created surface " + this);
6899 }
6900 return mSurface;
6901 }
Romain Guy06882f82009-06-10 13:36:04 -07006902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 if (mAppToken != null && this == mAppToken.startingWindow) {
6905 mAppToken.startingDisplayed = false;
6906 }
Romain Guy06882f82009-06-10 13:36:04 -07006907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006909 mDrawPending = false;
6910 mCommitDrawPending = false;
6911 mReadyToShow = false;
6912
6913 int i = mChildWindows.size();
6914 while (i > 0) {
6915 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006916 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006917 c.mAttachedHidden = true;
6918 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006919
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006920 if (mReportDestroySurface) {
6921 mReportDestroySurface = false;
6922 mSurfacePendingDestroy = true;
6923 try {
6924 mClient.dispatchGetNewSurface();
6925 // We'll really destroy on the next time around.
6926 return;
6927 } catch (RemoteException e) {
6928 }
6929 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006932 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006933 RuntimeException e = null;
6934 if (!HIDE_STACK_CRAWLS) {
6935 e = new RuntimeException();
6936 e.fillInStackTrace();
6937 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006938 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006939 + mSurface + ", session " + mSession, e);
6940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006942 RuntimeException e = null;
6943 if (!HIDE_STACK_CRAWLS) {
6944 e = new RuntimeException();
6945 e.fillInStackTrace();
6946 }
6947 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006949 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006951 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 + " surface " + mSurface + " session " + mSession
6953 + ": " + e.toString());
6954 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006955
Dianne Hackborn16064f92010-03-25 00:47:24 -07006956 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006958 }
6959 }
6960
6961 boolean finishDrawingLocked() {
6962 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006963 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 TAG, "finishDrawingLocked: " + mSurface);
6965 mCommitDrawPending = true;
6966 mDrawPending = false;
6967 return true;
6968 }
6969 return false;
6970 }
6971
6972 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006973 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006974 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006975 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006976 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 }
6978 mCommitDrawPending = false;
6979 mReadyToShow = true;
6980 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
6981 final AppWindowToken atoken = mAppToken;
6982 if (atoken == null || atoken.allDrawn || starting) {
6983 performShowLocked();
6984 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006985 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006986 }
6987
6988 // This must be called while inside a transaction.
6989 boolean performShowLocked() {
6990 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006991 RuntimeException e = null;
6992 if (!HIDE_STACK_CRAWLS) {
6993 e = new RuntimeException();
6994 e.fillInStackTrace();
6995 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006996 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006997 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
6998 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
6999 }
7000 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007001 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7002 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007003 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007004 + " during animation: policyVis=" + mPolicyVisibility
7005 + " attHidden=" + mAttachedHidden
7006 + " tok.hiddenRequested="
7007 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007008 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 + (mAppToken != null ? mAppToken.hidden : false)
7010 + " animating=" + mAnimating
7011 + " tok animating="
7012 + (mAppToken != null ? mAppToken.animating : false));
7013 if (!showSurfaceRobustlyLocked(this)) {
7014 return false;
7015 }
7016 mLastAlpha = -1;
7017 mHasDrawn = true;
7018 mLastHidden = false;
7019 mReadyToShow = false;
7020 enableScreenIfNeededLocked();
7021
7022 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 int i = mChildWindows.size();
7025 while (i > 0) {
7026 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007027 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007028 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007030 if (c.mSurface != null) {
7031 c.performShowLocked();
7032 // It hadn't been shown, which means layout not
7033 // performed on it, so now we want to make sure to
7034 // do a layout. If called from within the transaction
7035 // loop, this will cause it to restart with a new
7036 // layout.
7037 mLayoutNeeded = true;
7038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039 }
7040 }
Romain Guy06882f82009-06-10 13:36:04 -07007041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 if (mAttrs.type != TYPE_APPLICATION_STARTING
7043 && mAppToken != null) {
7044 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007045
Dianne Hackborn248b1882009-09-16 16:46:44 -07007046 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007047 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007048 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007049 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007050 // If this initial window is animating, stop it -- we
7051 // will do an animation to reveal it from behind the
7052 // starting window, so there is no need for it to also
7053 // be doing its own stuff.
7054 if (mAnimation != null) {
7055 mAnimation = null;
7056 // Make sure we clean up the animation.
7057 mAnimating = true;
7058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 mFinishedStarting.add(mAppToken);
7060 mH.sendEmptyMessage(H.FINISHED_STARTING);
7061 }
7062 mAppToken.updateReportedVisibilityLocked();
7063 }
7064 }
7065 return true;
7066 }
Romain Guy06882f82009-06-10 13:36:04 -07007067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 // This must be called while inside a transaction. Returns true if
7069 // there is more animation to run.
7070 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007071 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007072 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7075 mHasTransformation = true;
7076 mHasLocalTransformation = true;
7077 if (!mLocalAnimating) {
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, "Starting animation in " + this +
7080 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7081 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7082 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7083 mAnimation.setStartTime(currentTime);
7084 mLocalAnimating = true;
7085 mAnimating = true;
7086 }
7087 mTransformation.clear();
7088 final boolean more = mAnimation.getTransformation(
7089 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007090 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007091 TAG, "Stepped animation in " + this +
7092 ": more=" + more + ", xform=" + mTransformation);
7093 if (more) {
7094 // we're not done!
7095 return true;
7096 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007097 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 TAG, "Finished animation in " + this +
7099 " @ " + currentTime);
7100 mAnimation = null;
7101 //WindowManagerService.this.dump();
7102 }
7103 mHasLocalTransformation = false;
7104 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007105 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007106 // When our app token is animating, we kind-of pretend like
7107 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7108 // part of this check means that we will only do this if
7109 // our window is not currently exiting, or it is not
7110 // locally animating itself. The idea being that one that
7111 // is exiting and doing a local animation should be removed
7112 // once that animation is done.
7113 mAnimating = true;
7114 mHasTransformation = true;
7115 mTransformation.clear();
7116 return false;
7117 } else if (mHasTransformation) {
7118 // Little trick to get through the path below to act like
7119 // we have finished an animation.
7120 mAnimating = true;
7121 } else if (isAnimating()) {
7122 mAnimating = true;
7123 }
7124 } else if (mAnimation != null) {
7125 // If the display is frozen, and there is a pending animation,
7126 // clear it and make sure we run the cleanup code.
7127 mAnimating = true;
7128 mLocalAnimating = true;
7129 mAnimation = null;
7130 }
Romain Guy06882f82009-06-10 13:36:04 -07007131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 if (!mAnimating && !mLocalAnimating) {
7133 return false;
7134 }
7135
Joe Onorato8a9b2202010-02-26 18:56:32 -08007136 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 TAG, "Animation done in " + this + ": exiting=" + mExiting
7138 + ", reportedVisible="
7139 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 mAnimating = false;
7142 mLocalAnimating = false;
7143 mAnimation = null;
7144 mAnimLayer = mLayer;
7145 if (mIsImWindow) {
7146 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007147 } else if (mIsWallpaper) {
7148 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007150 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007151 + " anim layer: " + mAnimLayer);
7152 mHasTransformation = false;
7153 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007154 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7155 if (DEBUG_VISIBILITY) {
7156 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7157 + mPolicyVisibilityAfterAnim);
7158 }
7159 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7160 if (!mPolicyVisibility) {
7161 if (mCurrentFocus == this) {
7162 mFocusMayChange = true;
7163 }
7164 // Window is no longer visible -- make sure if we were waiting
7165 // for it to be displayed before enabling the display, that
7166 // we allow the display to be enabled now.
7167 enableScreenIfNeededLocked();
7168 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 mTransformation.clear();
7171 if (mHasDrawn
7172 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7173 && mAppToken != null
7174 && mAppToken.firstWindowDrawn
7175 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007176 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007177 + mToken + ": first real window done animating");
7178 mFinishedStarting.add(mAppToken);
7179 mH.sendEmptyMessage(H.FINISHED_STARTING);
7180 }
Romain Guy06882f82009-06-10 13:36:04 -07007181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 finishExit();
7183
7184 if (mAppToken != null) {
7185 mAppToken.updateReportedVisibilityLocked();
7186 }
7187
7188 return false;
7189 }
7190
7191 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007192 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 TAG, "finishExit in " + this
7194 + ": exiting=" + mExiting
7195 + " remove=" + mRemoveOnExit
7196 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 final int N = mChildWindows.size();
7199 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007200 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007201 }
Romain Guy06882f82009-06-10 13:36:04 -07007202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007203 if (!mExiting) {
7204 return;
7205 }
Romain Guy06882f82009-06-10 13:36:04 -07007206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007207 if (isWindowAnimating()) {
7208 return;
7209 }
7210
Joe Onorato8a9b2202010-02-26 18:56:32 -08007211 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 TAG, "Exit animation finished in " + this
7213 + ": remove=" + mRemoveOnExit);
7214 if (mSurface != null) {
7215 mDestroySurface.add(this);
7216 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007217 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007218 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007219 try {
7220 mSurface.hide();
7221 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007222 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 }
7224 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225 }
7226 mExiting = false;
7227 if (mRemoveOnExit) {
7228 mPendingRemove.add(this);
7229 mRemoveOnExit = false;
7230 }
7231 }
Romain Guy06882f82009-06-10 13:36:04 -07007232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7234 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7235 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7236 if (dtdx < -.000001f || dtdx > .000001f) return false;
7237 if (dsdy < -.000001f || dsdy > .000001f) return false;
7238 return true;
7239 }
Romain Guy06882f82009-06-10 13:36:04 -07007240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 void computeShownFrameLocked() {
7242 final boolean selfTransformation = mHasLocalTransformation;
7243 Transformation attachedTransformation =
7244 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7245 ? mAttachedWindow.mTransformation : null;
7246 Transformation appTransformation =
7247 (mAppToken != null && mAppToken.hasTransformation)
7248 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007249
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007250 // Wallpapers are animated based on the "real" window they
7251 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007252 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007253 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007254 if (mWallpaperTarget.mHasLocalTransformation &&
7255 mWallpaperTarget.mAnimation != null &&
7256 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007257 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007258 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007259 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007260 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007261 }
7262 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007263 mWallpaperTarget.mAppToken.hasTransformation &&
7264 mWallpaperTarget.mAppToken.animation != null &&
7265 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007266 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007267 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007268 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007269 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007270 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007271 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 if (selfTransformation || attachedTransformation != null
7274 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007275 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 final Rect frame = mFrame;
7277 final float tmpFloats[] = mTmpFloats;
7278 final Matrix tmpMatrix = mTmpMatrix;
7279
7280 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007281 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007283 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007284 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007285 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007286 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007287 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 }
7289 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007290 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 }
7292
7293 // "convert" it into SurfaceFlinger's format
7294 // (a 2x2 matrix + an offset)
7295 // Here we must not transform the position of the surface
7296 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007297 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 tmpMatrix.getValues(tmpFloats);
7300 mDsDx = tmpFloats[Matrix.MSCALE_X];
7301 mDtDx = tmpFloats[Matrix.MSKEW_X];
7302 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7303 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007304 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7305 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007306 int w = frame.width();
7307 int h = frame.height();
7308 mShownFrame.set(x, y, x+w, y+h);
7309
7310 // Now set the alpha... but because our current hardware
7311 // can't do alpha transformation on a non-opaque surface,
7312 // turn it off if we are running an animation that is also
7313 // transforming since it is more important to have that
7314 // animation be smooth.
7315 mShownAlpha = mAlpha;
7316 if (!mLimitedAlphaCompositing
7317 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7318 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7319 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007320 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 if (selfTransformation) {
7322 mShownAlpha *= mTransformation.getAlpha();
7323 }
7324 if (attachedTransformation != null) {
7325 mShownAlpha *= attachedTransformation.getAlpha();
7326 }
7327 if (appTransformation != null) {
7328 mShownAlpha *= appTransformation.getAlpha();
7329 }
7330 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007331 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 }
Romain Guy06882f82009-06-10 13:36:04 -07007333
Joe Onorato8a9b2202010-02-26 18:56:32 -08007334 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 TAG, "Continuing animation in " + this +
7336 ": " + mShownFrame +
7337 ", alpha=" + mTransformation.getAlpha());
7338 return;
7339 }
Romain Guy06882f82009-06-10 13:36:04 -07007340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007341 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007342 if (mXOffset != 0 || mYOffset != 0) {
7343 mShownFrame.offset(mXOffset, mYOffset);
7344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007345 mShownAlpha = mAlpha;
7346 mDsDx = 1;
7347 mDtDx = 0;
7348 mDsDy = 0;
7349 mDtDy = 1;
7350 }
Romain Guy06882f82009-06-10 13:36:04 -07007351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007352 /**
7353 * Is this window visible? It is not visible if there is no
7354 * surface, or we are in the process of running an exit animation
7355 * that will remove the surface, or its app token has been hidden.
7356 */
7357 public boolean isVisibleLw() {
7358 final AppWindowToken atoken = mAppToken;
7359 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7360 && (atoken == null || !atoken.hiddenRequested)
7361 && !mExiting && !mDestroying;
7362 }
7363
7364 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007365 * Like {@link #isVisibleLw}, but also counts a window that is currently
7366 * "hidden" behind the keyguard as visible. This allows us to apply
7367 * things like window flags that impact the keyguard.
7368 * XXX I am starting to think we need to have ANOTHER visibility flag
7369 * for this "hidden behind keyguard" state rather than overloading
7370 * mPolicyVisibility. Ungh.
7371 */
7372 public boolean isVisibleOrBehindKeyguardLw() {
7373 final AppWindowToken atoken = mAppToken;
7374 return mSurface != null && !mAttachedHidden
7375 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007376 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007377 && !mExiting && !mDestroying;
7378 }
7379
7380 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 * Is this window visible, ignoring its app token? It is not visible
7382 * if there is no surface, or we are in the process of running an exit animation
7383 * that will remove the surface.
7384 */
7385 public boolean isWinVisibleLw() {
7386 final AppWindowToken atoken = mAppToken;
7387 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7388 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7389 && !mExiting && !mDestroying;
7390 }
7391
7392 /**
7393 * The same as isVisible(), but follows the current hidden state of
7394 * the associated app token, not the pending requested hidden state.
7395 */
7396 boolean isVisibleNow() {
7397 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007398 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007399 }
7400
7401 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007402 * Can this window possibly be a drag/drop target? The test here is
7403 * a combination of the above "visible now" with the check that the
7404 * Input Manager uses when discarding windows from input consideration.
7405 */
7406 boolean isPotentialDragTarget() {
7407 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7408 }
7409
7410 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007411 * Same as isVisible(), but we also count it as visible between the
7412 * call to IWindowSession.add() and the first relayout().
7413 */
7414 boolean isVisibleOrAdding() {
7415 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007416 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7418 && mPolicyVisibility && !mAttachedHidden
7419 && (atoken == null || !atoken.hiddenRequested)
7420 && !mExiting && !mDestroying;
7421 }
7422
7423 /**
7424 * Is this window currently on-screen? It is on-screen either if it
7425 * is visible or it is currently running an animation before no longer
7426 * being visible.
7427 */
7428 boolean isOnScreen() {
7429 final AppWindowToken atoken = mAppToken;
7430 if (atoken != null) {
7431 return mSurface != null && mPolicyVisibility && !mDestroying
7432 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007433 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 } else {
7435 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007436 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
7438 }
Romain Guy06882f82009-06-10 13:36:04 -07007439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007440 /**
7441 * Like isOnScreen(), but we don't return true if the window is part
7442 * of a transition that has not yet been started.
7443 */
7444 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007445 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007446 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007447 return false;
7448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007450 final boolean animating = atoken != null
7451 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007453 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7454 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007455 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 }
7457
7458 /** Is the window or its container currently animating? */
7459 boolean isAnimating() {
7460 final WindowState attached = mAttachedWindow;
7461 final AppWindowToken atoken = mAppToken;
7462 return mAnimation != null
7463 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007464 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 (atoken.animation != null
7466 || atoken.inPendingTransaction));
7467 }
7468
7469 /** Is this window currently animating? */
7470 boolean isWindowAnimating() {
7471 return mAnimation != null;
7472 }
7473
7474 /**
7475 * Like isOnScreen, but returns false if the surface hasn't yet
7476 * been drawn.
7477 */
7478 public boolean isDisplayedLw() {
7479 final AppWindowToken atoken = mAppToken;
7480 return mSurface != null && mPolicyVisibility && !mDestroying
7481 && !mDrawPending && !mCommitDrawPending
7482 && ((!mAttachedHidden &&
7483 (atoken == null || !atoken.hiddenRequested))
7484 || mAnimating);
7485 }
7486
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007487 /**
7488 * Returns true if the window has a surface that it has drawn a
7489 * complete UI in to.
7490 */
7491 public boolean isDrawnLw() {
7492 final AppWindowToken atoken = mAppToken;
7493 return mSurface != null && !mDestroying
7494 && !mDrawPending && !mCommitDrawPending;
7495 }
7496
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007497 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007498 * Return true if the window is opaque and fully drawn. This indicates
7499 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007500 */
7501 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007502 return (mAttrs.format == PixelFormat.OPAQUE
7503 || mAttrs.type == TYPE_WALLPAPER)
7504 && mSurface != null && mAnimation == null
7505 && (mAppToken == null || mAppToken.animation == null)
7506 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007507 }
7508
7509 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7510 return
7511 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007512 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7513 // only if it's visible
7514 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007515 // and only if the application fills the compatible screen
7516 mFrame.left <= mCompatibleScreenFrame.left &&
7517 mFrame.top <= mCompatibleScreenFrame.top &&
7518 mFrame.right >= mCompatibleScreenFrame.right &&
7519 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007520 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007521 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007522 }
7523
7524 boolean isFullscreen(int screenWidth, int screenHeight) {
7525 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007526 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 }
7528
7529 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007530 disposeInputChannel();
7531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007532 if (mAttachedWindow != null) {
7533 mAttachedWindow.mChildWindows.remove(this);
7534 }
7535 destroySurfaceLocked();
7536 mSession.windowRemovedLocked();
7537 try {
7538 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7539 } catch (RuntimeException e) {
7540 // Ignore if it has already been removed (usually because
7541 // we are doing this as part of processing a death note.)
7542 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007543 }
7544
7545 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007546 if (mInputChannel != null) {
7547 mInputManager.unregisterInputChannel(mInputChannel);
7548
7549 mInputChannel.dispose();
7550 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007552 }
7553
7554 private class DeathRecipient implements IBinder.DeathRecipient {
7555 public void binderDied() {
7556 try {
7557 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007558 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007559 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007560 if (win != null) {
7561 removeWindowLocked(mSession, win);
7562 }
7563 }
7564 } catch (IllegalArgumentException ex) {
7565 // This will happen if the window has already been
7566 // removed.
7567 }
7568 }
7569 }
7570
7571 /** Returns true if this window desires key events. */
7572 public final boolean canReceiveKeys() {
7573 return isVisibleOrAdding()
7574 && (mViewVisibility == View.VISIBLE)
7575 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7576 }
7577
7578 public boolean hasDrawnLw() {
7579 return mHasDrawn;
7580 }
7581
7582 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007583 return showLw(doAnimation, true);
7584 }
7585
7586 boolean showLw(boolean doAnimation, boolean requestAnim) {
7587 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7588 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007590 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007591 if (doAnimation) {
7592 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7593 + mPolicyVisibility + " mAnimation=" + mAnimation);
7594 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7595 doAnimation = false;
7596 } else if (mPolicyVisibility && mAnimation == null) {
7597 // Check for the case where we are currently visible and
7598 // not animating; we do not want to do animation at such a
7599 // point to become visible when we already are.
7600 doAnimation = false;
7601 }
7602 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007603 mPolicyVisibility = true;
7604 mPolicyVisibilityAfterAnim = true;
7605 if (doAnimation) {
7606 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7607 }
7608 if (requestAnim) {
7609 requestAnimationLocked(0);
7610 }
7611 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007612 }
7613
7614 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007615 return hideLw(doAnimation, true);
7616 }
7617
7618 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007619 if (doAnimation) {
7620 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7621 doAnimation = false;
7622 }
7623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007624 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7625 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007626 if (!current) {
7627 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007629 if (doAnimation) {
7630 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7631 if (mAnimation == null) {
7632 doAnimation = false;
7633 }
7634 }
7635 if (doAnimation) {
7636 mPolicyVisibilityAfterAnim = false;
7637 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007638 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007639 mPolicyVisibilityAfterAnim = false;
7640 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007641 // Window is no longer visible -- make sure if we were waiting
7642 // for it to be displayed before enabling the display, that
7643 // we allow the display to be enabled now.
7644 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007645 if (mCurrentFocus == this) {
7646 mFocusMayChange = true;
7647 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007648 }
7649 if (requestAnim) {
7650 requestAnimationLocked(0);
7651 }
7652 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007653 }
7654
7655 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007656 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7657 pw.print(" mClient="); pw.println(mClient.asBinder());
7658 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7659 if (mAttachedWindow != null || mLayoutAttached) {
7660 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7661 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7662 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007663 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7664 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7665 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007666 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7667 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007668 }
7669 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7670 pw.print(" mSubLayer="); pw.print(mSubLayer);
7671 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7672 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7673 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7674 pw.print("="); pw.print(mAnimLayer);
7675 pw.print(" mLastLayer="); pw.println(mLastLayer);
7676 if (mSurface != null) {
7677 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007678 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7679 pw.print(" layer="); pw.print(mSurfaceLayer);
7680 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7681 pw.print(" rect=("); pw.print(mSurfaceX);
7682 pw.print(","); pw.print(mSurfaceY);
7683 pw.print(") "); pw.print(mSurfaceW);
7684 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007685 }
7686 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7687 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7688 if (mAppToken != null) {
7689 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7690 }
7691 if (mTargetAppToken != null) {
7692 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7693 }
7694 pw.print(prefix); pw.print("mViewVisibility=0x");
7695 pw.print(Integer.toHexString(mViewVisibility));
7696 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007697 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7698 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007699 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7700 pw.print(prefix); pw.print("mPolicyVisibility=");
7701 pw.print(mPolicyVisibility);
7702 pw.print(" mPolicyVisibilityAfterAnim=");
7703 pw.print(mPolicyVisibilityAfterAnim);
7704 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7705 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007706 if (!mRelayoutCalled) {
7707 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7708 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007709 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007710 pw.print(" h="); pw.print(mRequestedHeight);
7711 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007712 if (mXOffset != 0 || mYOffset != 0) {
7713 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7714 pw.print(" y="); pw.println(mYOffset);
7715 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007716 pw.print(prefix); pw.print("mGivenContentInsets=");
7717 mGivenContentInsets.printShortString(pw);
7718 pw.print(" mGivenVisibleInsets=");
7719 mGivenVisibleInsets.printShortString(pw);
7720 pw.println();
7721 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7722 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7723 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7724 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007725 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007726 pw.print(prefix); pw.print("mShownFrame=");
7727 mShownFrame.printShortString(pw);
7728 pw.print(" last="); mLastShownFrame.printShortString(pw);
7729 pw.println();
7730 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7731 pw.print(" last="); mLastFrame.printShortString(pw);
7732 pw.println();
7733 pw.print(prefix); pw.print("mContainingFrame=");
7734 mContainingFrame.printShortString(pw);
7735 pw.print(" mDisplayFrame=");
7736 mDisplayFrame.printShortString(pw);
7737 pw.println();
7738 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7739 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7740 pw.println();
7741 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7742 pw.print(" last="); mLastContentInsets.printShortString(pw);
7743 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7744 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7745 pw.println();
7746 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7747 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7748 pw.print(" mAlpha="); pw.print(mAlpha);
7749 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7750 }
7751 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7752 || mAnimation != null) {
7753 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7754 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7755 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7756 pw.print(" mAnimation="); pw.println(mAnimation);
7757 }
7758 if (mHasTransformation || mHasLocalTransformation) {
7759 pw.print(prefix); pw.print("XForm: has=");
7760 pw.print(mHasTransformation);
7761 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7762 pw.print(" "); mTransformation.printShortString(pw);
7763 pw.println();
7764 }
7765 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7766 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7767 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7768 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7769 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7770 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7771 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7772 pw.print(" mDestroying="); pw.print(mDestroying);
7773 pw.print(" mRemoved="); pw.println(mRemoved);
7774 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007775 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007776 pw.print(prefix); pw.print("mOrientationChanging=");
7777 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007778 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7779 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007780 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007781 if (mHScale != 1 || mVScale != 1) {
7782 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7783 pw.print(" mVScale="); pw.println(mVScale);
7784 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007785 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007786 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7787 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7788 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007789 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7790 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7791 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007793 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007794
7795 String makeInputChannelName() {
7796 return Integer.toHexString(System.identityHashCode(this))
7797 + " " + mAttrs.getTitle();
7798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799
7800 @Override
7801 public String toString() {
7802 return "Window{"
7803 + Integer.toHexString(System.identityHashCode(this))
7804 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7805 }
7806 }
Romain Guy06882f82009-06-10 13:36:04 -07007807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 // -------------------------------------------------------------
7809 // Window Token State
7810 // -------------------------------------------------------------
7811
7812 class WindowToken {
7813 // The actual token.
7814 final IBinder token;
7815
7816 // The type of window this token is for, as per WindowManager.LayoutParams.
7817 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07007818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 // Set if this token was explicitly added by a client, so should
7820 // not be removed when all windows are removed.
7821 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07007822
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007823 // For printing.
7824 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07007825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 // If this is an AppWindowToken, this is non-null.
7827 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07007828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007829 // All of the windows associated with this token.
7830 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
7831
7832 // Is key dispatching paused for this token?
7833 boolean paused = false;
7834
7835 // Should this token's windows be hidden?
7836 boolean hidden;
7837
7838 // Temporary for finding which tokens no longer have visible windows.
7839 boolean hasVisible;
7840
Dianne Hackborna8f60182009-09-01 19:01:50 -07007841 // Set to true when this token is in a pending transaction where it
7842 // will be shown.
7843 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007844
Dianne Hackborna8f60182009-09-01 19:01:50 -07007845 // Set to true when this token is in a pending transaction where it
7846 // will be hidden.
7847 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007848
Dianne Hackborna8f60182009-09-01 19:01:50 -07007849 // Set to true when this token is in a pending transaction where its
7850 // windows will be put to the bottom of the list.
7851 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007852
Dianne Hackborna8f60182009-09-01 19:01:50 -07007853 // Set to true when this token is in a pending transaction where its
7854 // windows will be put to the top of the list.
7855 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 WindowToken(IBinder _token, int type, boolean _explicit) {
7858 token = _token;
7859 windowType = type;
7860 explicit = _explicit;
7861 }
7862
7863 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007864 pw.print(prefix); pw.print("token="); pw.println(token);
7865 pw.print(prefix); pw.print("windows="); pw.println(windows);
7866 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
7867 pw.print(" hidden="); pw.print(hidden);
7868 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007869 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
7870 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
7871 pw.print(" waitingToHide="); pw.print(waitingToHide);
7872 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
7873 pw.print(" sendingToTop="); pw.println(sendingToTop);
7874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007875 }
7876
7877 @Override
7878 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007879 if (stringName == null) {
7880 StringBuilder sb = new StringBuilder();
7881 sb.append("WindowToken{");
7882 sb.append(Integer.toHexString(System.identityHashCode(this)));
7883 sb.append(" token="); sb.append(token); sb.append('}');
7884 stringName = sb.toString();
7885 }
7886 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 }
7888 };
7889
7890 class AppWindowToken extends WindowToken {
7891 // Non-null only for application tokens.
7892 final IApplicationToken appToken;
7893
7894 // All of the windows and child windows that are included in this
7895 // application token. Note this list is NOT sorted!
7896 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
7897
7898 int groupId = -1;
7899 boolean appFullscreen;
7900 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07007901
7902 // The input dispatching timeout for this application token in nanoseconds.
7903 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07007904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905 // These are used for determining when all windows associated with
7906 // an activity have been drawn, so they can be made visible together
7907 // at the same time.
7908 int lastTransactionSequence = mTransactionSequence-1;
7909 int numInterestingWindows;
7910 int numDrawnWindows;
7911 boolean inPendingTransaction;
7912 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07007913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007914 // Is this token going to be hidden in a little while? If so, it
7915 // won't be taken into account for setting the screen orientation.
7916 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007918 // Is this window's surface needed? This is almost like hidden, except
7919 // it will sometimes be true a little earlier: when the token has
7920 // been shown, but is still waiting for its app transition to execute
7921 // before making its windows shown.
7922 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07007923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924 // Have we told the window clients to hide themselves?
7925 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 // Last visibility state we reported to the app token.
7928 boolean reportedVisible;
7929
7930 // Set to true when the token has been removed from the window mgr.
7931 boolean removed;
7932
7933 // Have we been asked to have this token keep the screen frozen?
7934 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07007935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 boolean animating;
7937 Animation animation;
7938 boolean hasTransformation;
7939 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07007940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007941 // Offset to the window of all layers in the token, for use by
7942 // AppWindowToken animations.
7943 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07007944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945 // Information about an application starting window if displayed.
7946 StartingData startingData;
7947 WindowState startingWindow;
7948 View startingView;
7949 boolean startingDisplayed;
7950 boolean startingMoved;
7951 boolean firstWindowDrawn;
7952
7953 AppWindowToken(IApplicationToken _token) {
7954 super(_token.asBinder(),
7955 WindowManager.LayoutParams.TYPE_APPLICATION, true);
7956 appWindowToken = this;
7957 appToken = _token;
7958 }
Romain Guy06882f82009-06-10 13:36:04 -07007959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007960 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007961 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962 TAG, "Setting animation in " + this + ": " + anim);
7963 animation = anim;
7964 animating = false;
7965 anim.restrictDuration(MAX_ANIMATION_DURATION);
7966 anim.scaleCurrentDuration(mTransitionAnimationScale);
7967 int zorder = anim.getZAdjustment();
7968 int adj = 0;
7969 if (zorder == Animation.ZORDER_TOP) {
7970 adj = TYPE_LAYER_OFFSET;
7971 } else if (zorder == Animation.ZORDER_BOTTOM) {
7972 adj = -TYPE_LAYER_OFFSET;
7973 }
Romain Guy06882f82009-06-10 13:36:04 -07007974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 if (animLayerAdjustment != adj) {
7976 animLayerAdjustment = adj;
7977 updateLayers();
7978 }
7979 }
Romain Guy06882f82009-06-10 13:36:04 -07007980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007981 public void setDummyAnimation() {
7982 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007983 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 TAG, "Setting dummy animation in " + this);
7985 animation = sDummyAnimation;
7986 }
7987 }
7988
7989 public void clearAnimation() {
7990 if (animation != null) {
7991 animation = null;
7992 animating = true;
7993 }
7994 }
Romain Guy06882f82009-06-10 13:36:04 -07007995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007996 void updateLayers() {
7997 final int N = allAppWindows.size();
7998 final int adj = animLayerAdjustment;
7999 for (int i=0; i<N; i++) {
8000 WindowState w = allAppWindows.get(i);
8001 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008002 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003 + w.mAnimLayer);
8004 if (w == mInputMethodTarget) {
8005 setInputMethodAnimLayerAdjustment(adj);
8006 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008007 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008008 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010 }
8011 }
Romain Guy06882f82009-06-10 13:36:04 -07008012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008013 void sendAppVisibilityToClients() {
8014 final int N = allAppWindows.size();
8015 for (int i=0; i<N; i++) {
8016 WindowState win = allAppWindows.get(i);
8017 if (win == startingWindow && clientHidden) {
8018 // Don't hide the starting window.
8019 continue;
8020 }
8021 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008022 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008023 "Setting visibility of " + win + ": " + (!clientHidden));
8024 win.mClient.dispatchAppVisibility(!clientHidden);
8025 } catch (RemoteException e) {
8026 }
8027 }
8028 }
Romain Guy06882f82009-06-10 13:36:04 -07008029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008030 void showAllWindowsLocked() {
8031 final int NW = allAppWindows.size();
8032 for (int i=0; i<NW; i++) {
8033 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008034 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008035 "performing show on: " + w);
8036 w.performShowLocked();
8037 }
8038 }
Romain Guy06882f82009-06-10 13:36:04 -07008039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008040 // This must be called while inside a transaction.
8041 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008042 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 if (animation == sDummyAnimation) {
8046 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008047 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048 // when it is really time to animate, this will be set to
8049 // a real animation and the next call will execute normally.
8050 return false;
8051 }
Romain Guy06882f82009-06-10 13:36:04 -07008052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008053 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8054 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008055 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 TAG, "Starting animation in " + this +
8057 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8058 + " scale=" + mTransitionAnimationScale
8059 + " allDrawn=" + allDrawn + " animating=" + animating);
8060 animation.initialize(dw, dh, dw, dh);
8061 animation.setStartTime(currentTime);
8062 animating = true;
8063 }
8064 transformation.clear();
8065 final boolean more = animation.getTransformation(
8066 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008067 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 TAG, "Stepped animation in " + this +
8069 ": more=" + more + ", xform=" + transformation);
8070 if (more) {
8071 // we're done!
8072 hasTransformation = true;
8073 return true;
8074 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008075 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008076 TAG, "Finished animation in " + this +
8077 " @ " + currentTime);
8078 animation = null;
8079 }
8080 } else if (animation != null) {
8081 // If the display is frozen, and there is a pending animation,
8082 // clear it and make sure we run the cleanup code.
8083 animating = true;
8084 animation = null;
8085 }
8086
8087 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089 if (!animating) {
8090 return false;
8091 }
8092
8093 clearAnimation();
8094 animating = false;
8095 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8096 moveInputMethodWindowsIfNeededLocked(true);
8097 }
Romain Guy06882f82009-06-10 13:36:04 -07008098
Joe Onorato8a9b2202010-02-26 18:56:32 -08008099 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 TAG, "Animation done in " + this
8101 + ": reportedVisible=" + reportedVisible);
8102
8103 transformation.clear();
8104 if (animLayerAdjustment != 0) {
8105 animLayerAdjustment = 0;
8106 updateLayers();
8107 }
Romain Guy06882f82009-06-10 13:36:04 -07008108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008109 final int N = windows.size();
8110 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008111 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008112 }
8113 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008115 return false;
8116 }
8117
8118 void updateReportedVisibilityLocked() {
8119 if (appToken == null) {
8120 return;
8121 }
Romain Guy06882f82009-06-10 13:36:04 -07008122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008123 int numInteresting = 0;
8124 int numVisible = 0;
8125 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008126
Joe Onorato8a9b2202010-02-26 18:56:32 -08008127 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008128 final int N = allAppWindows.size();
8129 for (int i=0; i<N; i++) {
8130 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008131 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008132 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008133 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8134 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008135 continue;
8136 }
8137 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008138 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008139 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008141 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008142 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143 + " pv=" + win.mPolicyVisibility
8144 + " dp=" + win.mDrawPending
8145 + " cdp=" + win.mCommitDrawPending
8146 + " ah=" + win.mAttachedHidden
8147 + " th="
8148 + (win.mAppToken != null
8149 ? win.mAppToken.hiddenRequested : false)
8150 + " a=" + win.mAnimating);
8151 }
8152 }
8153 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008154 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 if (!win.isAnimating()) {
8156 numVisible++;
8157 }
8158 nowGone = false;
8159 } else if (win.isAnimating()) {
8160 nowGone = false;
8161 }
8162 }
Romain Guy06882f82009-06-10 13:36:04 -07008163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008165 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 + numInteresting + " visible=" + numVisible);
8167 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008168 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008169 TAG, "Visibility changed in " + this
8170 + ": vis=" + nowVisible);
8171 reportedVisible = nowVisible;
8172 Message m = mH.obtainMessage(
8173 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8174 nowVisible ? 1 : 0,
8175 nowGone ? 1 : 0,
8176 this);
8177 mH.sendMessage(m);
8178 }
8179 }
Romain Guy06882f82009-06-10 13:36:04 -07008180
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008181 WindowState findMainWindow() {
8182 int j = windows.size();
8183 while (j > 0) {
8184 j--;
8185 WindowState win = windows.get(j);
8186 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8187 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8188 return win;
8189 }
8190 }
8191 return null;
8192 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 void dump(PrintWriter pw, String prefix) {
8195 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008196 if (appToken != null) {
8197 pw.print(prefix); pw.println("app=true");
8198 }
8199 if (allAppWindows.size() > 0) {
8200 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8201 }
8202 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008203 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008204 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8205 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8206 pw.print(" clientHidden="); pw.print(clientHidden);
8207 pw.print(" willBeHidden="); pw.print(willBeHidden);
8208 pw.print(" reportedVisible="); pw.println(reportedVisible);
8209 if (paused || freezingScreen) {
8210 pw.print(prefix); pw.print("paused="); pw.print(paused);
8211 pw.print(" freezingScreen="); pw.println(freezingScreen);
8212 }
8213 if (numInterestingWindows != 0 || numDrawnWindows != 0
8214 || inPendingTransaction || allDrawn) {
8215 pw.print(prefix); pw.print("numInterestingWindows=");
8216 pw.print(numInterestingWindows);
8217 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8218 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8219 pw.print(" allDrawn="); pw.println(allDrawn);
8220 }
8221 if (animating || animation != null) {
8222 pw.print(prefix); pw.print("animating="); pw.print(animating);
8223 pw.print(" animation="); pw.println(animation);
8224 }
8225 if (animLayerAdjustment != 0) {
8226 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8227 }
8228 if (hasTransformation) {
8229 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8230 pw.print(" transformation="); transformation.printShortString(pw);
8231 pw.println();
8232 }
8233 if (startingData != null || removed || firstWindowDrawn) {
8234 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8235 pw.print(" removed="); pw.print(removed);
8236 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8237 }
8238 if (startingWindow != null || startingView != null
8239 || startingDisplayed || startingMoved) {
8240 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8241 pw.print(" startingView="); pw.print(startingView);
8242 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8243 pw.print(" startingMoved"); pw.println(startingMoved);
8244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008245 }
8246
8247 @Override
8248 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008249 if (stringName == null) {
8250 StringBuilder sb = new StringBuilder();
8251 sb.append("AppWindowToken{");
8252 sb.append(Integer.toHexString(System.identityHashCode(this)));
8253 sb.append(" token="); sb.append(token); sb.append('}');
8254 stringName = sb.toString();
8255 }
8256 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008257 }
8258 }
Romain Guy06882f82009-06-10 13:36:04 -07008259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008260 // -------------------------------------------------------------
8261 // DummyAnimation
8262 // -------------------------------------------------------------
8263
8264 // This is an animation that does nothing: it just immediately finishes
8265 // itself every time it is called. It is used as a stub animation in cases
8266 // where we want to synchronize multiple things that may be animating.
8267 static final class DummyAnimation extends Animation {
8268 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8269 return false;
8270 }
8271 }
8272 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008274 // -------------------------------------------------------------
8275 // Async Handler
8276 // -------------------------------------------------------------
8277
8278 static final class StartingData {
8279 final String pkg;
8280 final int theme;
8281 final CharSequence nonLocalizedLabel;
8282 final int labelRes;
8283 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07008284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
8286 int _labelRes, int _icon) {
8287 pkg = _pkg;
8288 theme = _theme;
8289 nonLocalizedLabel = _nonLocalizedLabel;
8290 labelRes = _labelRes;
8291 icon = _icon;
8292 }
8293 }
8294
8295 private final class H extends Handler {
8296 public static final int REPORT_FOCUS_CHANGE = 2;
8297 public static final int REPORT_LOSING_FOCUS = 3;
8298 public static final int ANIMATE = 4;
8299 public static final int ADD_STARTING = 5;
8300 public static final int REMOVE_STARTING = 6;
8301 public static final int FINISHED_STARTING = 7;
8302 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008303 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8304 public static final int HOLD_SCREEN_CHANGED = 12;
8305 public static final int APP_TRANSITION_TIMEOUT = 13;
8306 public static final int PERSIST_ANIMATION_SCALE = 14;
8307 public static final int FORCE_GC = 15;
8308 public static final int ENABLE_SCREEN = 16;
8309 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008310 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008311 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008312 public static final int DRAG_START_TIMEOUT = 20;
Romain Guy06882f82009-06-10 13:36:04 -07008313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008314 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008316 public H() {
8317 }
Romain Guy06882f82009-06-10 13:36:04 -07008318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 @Override
8320 public void handleMessage(Message msg) {
8321 switch (msg.what) {
8322 case REPORT_FOCUS_CHANGE: {
8323 WindowState lastFocus;
8324 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 synchronized(mWindowMap) {
8327 lastFocus = mLastFocus;
8328 newFocus = mCurrentFocus;
8329 if (lastFocus == newFocus) {
8330 // Focus is not changing, so nothing to do.
8331 return;
8332 }
8333 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008334 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008335 // + " to " + newFocus);
8336 if (newFocus != null && lastFocus != null
8337 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008338 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 mLosingFocus.add(lastFocus);
8340 lastFocus = null;
8341 }
8342 }
8343
8344 if (lastFocus != newFocus) {
8345 //System.out.println("Changing focus from " + lastFocus
8346 // + " to " + newFocus);
8347 if (newFocus != null) {
8348 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008349 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008350 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8351 } catch (RemoteException e) {
8352 // Ignore if process has died.
8353 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008354 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 }
8356
8357 if (lastFocus != null) {
8358 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008359 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008360 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8361 } catch (RemoteException e) {
8362 // Ignore if process has died.
8363 }
8364 }
8365 }
8366 } break;
8367
8368 case REPORT_LOSING_FOCUS: {
8369 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 synchronized(mWindowMap) {
8372 losers = mLosingFocus;
8373 mLosingFocus = new ArrayList<WindowState>();
8374 }
8375
8376 final int N = losers.size();
8377 for (int i=0; i<N; i++) {
8378 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008379 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8381 } catch (RemoteException e) {
8382 // Ignore if process has died.
8383 }
8384 }
8385 } break;
8386
8387 case ANIMATE: {
8388 synchronized(mWindowMap) {
8389 mAnimationPending = false;
8390 performLayoutAndPlaceSurfacesLocked();
8391 }
8392 } break;
8393
8394 case ADD_STARTING: {
8395 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8396 final StartingData sd = wtoken.startingData;
8397
8398 if (sd == null) {
8399 // Animation has been canceled... do nothing.
8400 return;
8401 }
Romain Guy06882f82009-06-10 13:36:04 -07008402
Joe Onorato8a9b2202010-02-26 18:56:32 -08008403 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008404 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008406 View view = null;
8407 try {
8408 view = mPolicy.addStartingWindow(
8409 wtoken.token, sd.pkg,
8410 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
8411 sd.icon);
8412 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008413 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008414 }
8415
8416 if (view != null) {
8417 boolean abort = false;
8418
8419 synchronized(mWindowMap) {
8420 if (wtoken.removed || wtoken.startingData == null) {
8421 // If the window was successfully added, then
8422 // we need to remove it.
8423 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008424 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 "Aborted starting " + wtoken
8426 + ": removed=" + wtoken.removed
8427 + " startingData=" + wtoken.startingData);
8428 wtoken.startingWindow = null;
8429 wtoken.startingData = null;
8430 abort = true;
8431 }
8432 } else {
8433 wtoken.startingView = view;
8434 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008435 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008436 "Added starting " + wtoken
8437 + ": startingWindow="
8438 + wtoken.startingWindow + " startingView="
8439 + wtoken.startingView);
8440 }
8441
8442 if (abort) {
8443 try {
8444 mPolicy.removeStartingWindow(wtoken.token, view);
8445 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008446 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008447 }
8448 }
8449 }
8450 } break;
8451
8452 case REMOVE_STARTING: {
8453 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8454 IBinder token = null;
8455 View view = null;
8456 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008457 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458 + wtoken + ": startingWindow="
8459 + wtoken.startingWindow + " startingView="
8460 + wtoken.startingView);
8461 if (wtoken.startingWindow != null) {
8462 view = wtoken.startingView;
8463 token = wtoken.token;
8464 wtoken.startingData = null;
8465 wtoken.startingView = null;
8466 wtoken.startingWindow = null;
8467 }
8468 }
8469 if (view != null) {
8470 try {
8471 mPolicy.removeStartingWindow(token, view);
8472 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008473 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 }
8475 }
8476 } break;
8477
8478 case FINISHED_STARTING: {
8479 IBinder token = null;
8480 View view = null;
8481 while (true) {
8482 synchronized (mWindowMap) {
8483 final int N = mFinishedStarting.size();
8484 if (N <= 0) {
8485 break;
8486 }
8487 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8488
Joe Onorato8a9b2202010-02-26 18:56:32 -08008489 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008490 "Finished starting " + wtoken
8491 + ": startingWindow=" + wtoken.startingWindow
8492 + " startingView=" + wtoken.startingView);
8493
8494 if (wtoken.startingWindow == null) {
8495 continue;
8496 }
8497
8498 view = wtoken.startingView;
8499 token = wtoken.token;
8500 wtoken.startingData = null;
8501 wtoken.startingView = null;
8502 wtoken.startingWindow = null;
8503 }
8504
8505 try {
8506 mPolicy.removeStartingWindow(token, view);
8507 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008508 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008509 }
8510 }
8511 } break;
8512
8513 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8514 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8515
8516 boolean nowVisible = msg.arg1 != 0;
8517 boolean nowGone = msg.arg2 != 0;
8518
8519 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008520 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 TAG, "Reporting visible in " + wtoken
8522 + " visible=" + nowVisible
8523 + " gone=" + nowGone);
8524 if (nowVisible) {
8525 wtoken.appToken.windowsVisible();
8526 } else {
8527 wtoken.appToken.windowsGone();
8528 }
8529 } catch (RemoteException ex) {
8530 }
8531 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 case WINDOW_FREEZE_TIMEOUT: {
8534 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008535 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 int i = mWindows.size();
8537 while (i > 0) {
8538 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008539 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008540 if (w.mOrientationChanging) {
8541 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008542 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 }
8544 }
8545 performLayoutAndPlaceSurfacesLocked();
8546 }
8547 break;
8548 }
Romain Guy06882f82009-06-10 13:36:04 -07008549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008550 case HOLD_SCREEN_CHANGED: {
8551 Session oldHold;
8552 Session newHold;
8553 synchronized (mWindowMap) {
8554 oldHold = mLastReportedHold;
8555 newHold = (Session)msg.obj;
8556 mLastReportedHold = newHold;
8557 }
Romain Guy06882f82009-06-10 13:36:04 -07008558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008559 if (oldHold != newHold) {
8560 try {
8561 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008562 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563 "window",
8564 BatteryStats.WAKE_TYPE_WINDOW);
8565 }
8566 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008567 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 "window",
8569 BatteryStats.WAKE_TYPE_WINDOW);
8570 }
8571 } catch (RemoteException e) {
8572 }
8573 }
8574 break;
8575 }
Romain Guy06882f82009-06-10 13:36:04 -07008576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008577 case APP_TRANSITION_TIMEOUT: {
8578 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008579 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008580 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008581 "*** APP TRANSITION TIMEOUT");
8582 mAppTransitionReady = true;
8583 mAppTransitionTimeout = true;
8584 performLayoutAndPlaceSurfacesLocked();
8585 }
8586 }
8587 break;
8588 }
Romain Guy06882f82009-06-10 13:36:04 -07008589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 case PERSIST_ANIMATION_SCALE: {
8591 Settings.System.putFloat(mContext.getContentResolver(),
8592 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8593 Settings.System.putFloat(mContext.getContentResolver(),
8594 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8595 break;
8596 }
Romain Guy06882f82009-06-10 13:36:04 -07008597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598 case FORCE_GC: {
8599 synchronized(mWindowMap) {
8600 if (mAnimationPending) {
8601 // If we are animating, don't do the gc now but
8602 // delay a bit so we don't interrupt the animation.
8603 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8604 2000);
8605 return;
8606 }
8607 // If we are currently rotating the display, it will
8608 // schedule a new message when done.
8609 if (mDisplayFrozen) {
8610 return;
8611 }
8612 mFreezeGcPending = 0;
8613 }
8614 Runtime.getRuntime().gc();
8615 break;
8616 }
Romain Guy06882f82009-06-10 13:36:04 -07008617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 case ENABLE_SCREEN: {
8619 performEnableScreen();
8620 break;
8621 }
Romain Guy06882f82009-06-10 13:36:04 -07008622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008623 case APP_FREEZE_TIMEOUT: {
8624 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008625 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 int i = mAppTokens.size();
8627 while (i > 0) {
8628 i--;
8629 AppWindowToken tok = mAppTokens.get(i);
8630 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008631 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 unsetAppFreezingScreenLocked(tok, true, true);
8633 }
8634 }
8635 }
8636 break;
8637 }
Romain Guy06882f82009-06-10 13:36:04 -07008638
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008639 case SEND_NEW_CONFIGURATION: {
8640 removeMessages(SEND_NEW_CONFIGURATION);
8641 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008642 break;
8643 }
Romain Guy06882f82009-06-10 13:36:04 -07008644
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008645 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008646 if (mWindowsChanged) {
8647 synchronized (mWindowMap) {
8648 mWindowsChanged = false;
8649 }
8650 notifyWindowsChanged();
8651 }
8652 break;
8653 }
8654
Christopher Tatea53146c2010-09-07 11:57:52 -07008655 case DRAG_START_TIMEOUT: {
8656 IBinder win = (IBinder)msg.obj;
8657 if (DEBUG_DRAG) {
8658 Slog.w(TAG, "Timeout starting drag by win " + win);
8659 }
8660 synchronized (mWindowMap) {
8661 // !!! TODO: ANR the app that has failed to start the drag in time
8662 if (mDragState != null) {
8663 mDragState.reset();
8664 mDragState = null;
8665 }
8666 }
8667 }
8668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669 }
8670 }
8671 }
8672
8673 // -------------------------------------------------------------
8674 // IWindowManager API
8675 // -------------------------------------------------------------
8676
8677 public IWindowSession openSession(IInputMethodClient client,
8678 IInputContext inputContext) {
8679 if (client == null) throw new IllegalArgumentException("null client");
8680 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008681 Session session = new Session(client, inputContext);
8682 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683 }
8684
8685 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8686 synchronized (mWindowMap) {
8687 // The focus for the client is the window immediately below
8688 // where we would place the input method window.
8689 int idx = findDesiredInputMethodWindowIndexLocked(false);
8690 WindowState imFocus;
8691 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008692 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008693 if (imFocus != null) {
8694 if (imFocus.mSession.mClient != null &&
8695 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8696 return true;
8697 }
8698 }
8699 }
8700 }
8701 return false;
8702 }
Romain Guy06882f82009-06-10 13:36:04 -07008703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008704 // -------------------------------------------------------------
8705 // Internals
8706 // -------------------------------------------------------------
8707
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008708 final WindowState windowForClientLocked(Session session, IWindow client,
8709 boolean throwOnError) {
8710 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008711 }
Romain Guy06882f82009-06-10 13:36:04 -07008712
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008713 final WindowState windowForClientLocked(Session session, IBinder client,
8714 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008715 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008716 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008717 TAG, "Looking up client " + client + ": " + win);
8718 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008719 RuntimeException ex = new IllegalArgumentException(
8720 "Requested window " + client + " does not exist");
8721 if (throwOnError) {
8722 throw ex;
8723 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008724 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008725 return null;
8726 }
8727 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008728 RuntimeException ex = new IllegalArgumentException(
8729 "Requested window " + client + " is in session " +
8730 win.mSession + ", not " + session);
8731 if (throwOnError) {
8732 throw ex;
8733 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008734 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008735 return null;
8736 }
8737
8738 return win;
8739 }
8740
Dianne Hackborna8f60182009-09-01 19:01:50 -07008741 final void rebuildAppWindowListLocked() {
8742 int NW = mWindows.size();
8743 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008744 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008745 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008746
Dianne Hackborna8f60182009-09-01 19:01:50 -07008747 // First remove all existing app windows.
8748 i=0;
8749 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07008750 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008751 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07008752 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008753 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008754 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008755 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008756 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008757 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008758 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008759 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8760 && lastWallpaper == i-1) {
8761 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008762 }
8763 i++;
8764 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008765
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008766 // The wallpaper window(s) typically live at the bottom of the stack,
8767 // so skip them before adding app tokens.
8768 lastWallpaper++;
8769 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008770
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008771 // First add all of the exiting app tokens... these are no longer
8772 // in the main app list, but still have windows shown. We put them
8773 // in the back because now that the animation is over we no longer
8774 // will care about them.
8775 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008776 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008777 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8778 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008779
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008780 // And add in the still active app tokens in Z order.
8781 NT = mAppTokens.size();
8782 for (int j=0; j<NT; j++) {
8783 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008784 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008785
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008786 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008787 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008788 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008789 + " windows but added " + i);
8790 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008793 private final void assignLayersLocked() {
8794 int N = mWindows.size();
8795 int curBaseLayer = 0;
8796 int curLayer = 0;
8797 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008799 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008800 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008801 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8802 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008803 curLayer += WINDOW_LAYER_MULTIPLIER;
8804 w.mLayer = curLayer;
8805 } else {
8806 curBaseLayer = curLayer = w.mBaseLayer;
8807 w.mLayer = curLayer;
8808 }
8809 if (w.mTargetAppToken != null) {
8810 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
8811 } else if (w.mAppToken != null) {
8812 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
8813 } else {
8814 w.mAnimLayer = w.mLayer;
8815 }
8816 if (w.mIsImWindow) {
8817 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008818 } else if (w.mIsWallpaper) {
8819 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008821 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008822 + w.mAnimLayer);
8823 //System.out.println(
8824 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8825 }
8826 }
8827
8828 private boolean mInLayout = false;
8829 private final void performLayoutAndPlaceSurfacesLocked() {
8830 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008831 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008832 throw new RuntimeException("Recursive call!");
8833 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008834 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008835 return;
8836 }
8837
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008838 if (mWaitingForConfig) {
8839 // Our configuration has changed (most likely rotation), but we
8840 // don't yet have the complete configuration to report to
8841 // applications. Don't do any window layout until we have it.
8842 return;
8843 }
8844
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008845 if (mDisplay == null) {
8846 // Not yet initialized, nothing to do.
8847 return;
8848 }
8849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008850 boolean recoveringMemory = false;
8851 if (mForceRemoves != null) {
8852 recoveringMemory = true;
8853 // Wait a little it for things to settle down, and off we go.
8854 for (int i=0; i<mForceRemoves.size(); i++) {
8855 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008856 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008857 removeWindowInnerLocked(ws.mSession, ws);
8858 }
8859 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008860 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008861 Object tmp = new Object();
8862 synchronized (tmp) {
8863 try {
8864 tmp.wait(250);
8865 } catch (InterruptedException e) {
8866 }
8867 }
8868 }
Romain Guy06882f82009-06-10 13:36:04 -07008869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008870 mInLayout = true;
8871 try {
8872 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07008873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008874 int i = mPendingRemove.size()-1;
8875 if (i >= 0) {
8876 while (i >= 0) {
8877 WindowState w = mPendingRemove.get(i);
8878 removeWindowInnerLocked(w.mSession, w);
8879 i--;
8880 }
8881 mPendingRemove.clear();
8882
8883 mInLayout = false;
8884 assignLayersLocked();
8885 mLayoutNeeded = true;
8886 performLayoutAndPlaceSurfacesLocked();
8887
8888 } else {
8889 mInLayout = false;
8890 if (mLayoutNeeded) {
8891 requestAnimationLocked(0);
8892 }
8893 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008894 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008895 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8896 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008898 } catch (RuntimeException e) {
8899 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008900 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008901 }
8902 }
8903
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008904 private final int performLayoutLockedInner() {
8905 if (!mLayoutNeeded) {
8906 return 0;
8907 }
8908
8909 mLayoutNeeded = false;
8910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 final int dw = mDisplay.getWidth();
8912 final int dh = mDisplay.getHeight();
8913
8914 final int N = mWindows.size();
8915 int i;
8916
Joe Onorato8a9b2202010-02-26 18:56:32 -08008917 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008918 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
8919
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008920 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07008921
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008922 int seq = mLayoutSeq+1;
8923 if (seq < 0) seq = 0;
8924 mLayoutSeq = seq;
8925
8926 // First perform layout of any root windows (not attached
8927 // to another window).
8928 int topAttached = -1;
8929 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008930 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008931
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008932 // Don't do layout of a window if it is not visible, or
8933 // soon won't be visible, to avoid wasting time and funky
8934 // changes while a window is animating away.
8935 final AppWindowToken atoken = win.mAppToken;
8936 final boolean gone = win.mViewVisibility == View.GONE
8937 || !win.mRelayoutCalled
8938 || win.mRootToken.hidden
8939 || (atoken != null && atoken.hiddenRequested)
8940 || win.mAttachedHidden
8941 || win.mExiting || win.mDestroying;
8942
8943 if (!win.mLayoutAttached) {
8944 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
8945 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8946 + " mLayoutAttached=" + win.mLayoutAttached);
8947 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
8948 + win.mViewVisibility + " mRelayoutCalled="
8949 + win.mRelayoutCalled + " hidden="
8950 + win.mRootToken.hidden + " hiddenRequested="
8951 + (atoken != null && atoken.hiddenRequested)
8952 + " mAttachedHidden=" + win.mAttachedHidden);
8953 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008954
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008955 // If this view is GONE, then skip it -- keep the current
8956 // frame, and let the caller know so they can ignore it
8957 // if they want. (We do the normal layout for INVISIBLE
8958 // windows, since that means "perform layout as normal,
8959 // just don't display").
8960 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008961 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008962 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8963 win.mLayoutSeq = seq;
8964 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8965 + win.mFrame + " mContainingFrame="
8966 + win.mContainingFrame + " mDisplayFrame="
8967 + win.mDisplayFrame);
8968 } else {
8969 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008970 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008972 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008973
8974 // Now perform layout of attached windows, which usually
8975 // depend on the position of the window they are attached to.
8976 // XXX does not deal with windows that are attached to windows
8977 // that are themselves attached.
8978 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008979 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008980
8981 // If this view is GONE, then skip it -- keep the current
8982 // frame, and let the caller know so they can ignore it
8983 // if they want. (We do the normal layout for INVISIBLE
8984 // windows, since that means "perform layout as normal,
8985 // just don't display").
8986 if (win.mLayoutAttached) {
8987 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
8988 + " mHaveFrame=" + win.mHaveFrame
8989 + " mViewVisibility=" + win.mViewVisibility
8990 + " mRelayoutCalled=" + win.mRelayoutCalled);
8991 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
8992 || !win.mHaveFrame) {
8993 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8994 win.mLayoutSeq = seq;
8995 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8996 + win.mFrame + " mContainingFrame="
8997 + win.mContainingFrame + " mDisplayFrame="
8998 + win.mDisplayFrame);
8999 }
9000 }
9001 }
Jeff Brown349703e2010-06-22 01:27:15 -07009002
9003 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009004 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009005
9006 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 }
Romain Guy06882f82009-06-10 13:36:04 -07009008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 private final void performLayoutAndPlaceSurfacesLockedInner(
9010 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009011 if (mDisplay == null) {
9012 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9013 return;
9014 }
9015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 final long currentTime = SystemClock.uptimeMillis();
9017 final int dw = mDisplay.getWidth();
9018 final int dh = mDisplay.getHeight();
9019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 int i;
9021
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009022 if (mFocusMayChange) {
9023 mFocusMayChange = false;
9024 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9025 }
9026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009027 // Initialize state of exiting tokens.
9028 for (i=mExitingTokens.size()-1; i>=0; i--) {
9029 mExitingTokens.get(i).hasVisible = false;
9030 }
9031
9032 // Initialize state of exiting applications.
9033 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9034 mExitingAppTokens.get(i).hasVisible = false;
9035 }
9036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 boolean orientationChangeComplete = true;
9038 Session holdScreen = null;
9039 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009040 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009041 boolean focusDisplayed = false;
9042 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009043 boolean createWatermark = false;
9044
9045 if (mFxSession == null) {
9046 mFxSession = new SurfaceSession();
9047 createWatermark = true;
9048 }
9049
9050 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009051
9052 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009053
9054 if (createWatermark) {
9055 createWatermark();
9056 }
9057 if (mWatermark != null) {
9058 mWatermark.positionSurface(dw, dh);
9059 }
9060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009062 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009063 int repeats = 0;
9064 int changes = 0;
9065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009066 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009067 repeats++;
9068 if (repeats > 6) {
9069 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9070 mLayoutNeeded = false;
9071 break;
9072 }
9073
9074 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9075 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9076 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9077 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9078 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9079 assignLayersLocked();
9080 mLayoutNeeded = true;
9081 }
9082 }
9083 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9084 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9085 if (updateOrientationFromAppTokensLocked()) {
9086 mLayoutNeeded = true;
9087 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9088 }
9089 }
9090 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9091 mLayoutNeeded = true;
9092 }
9093 }
9094
9095 // FIRST LOOP: Perform a layout, if needed.
9096 if (repeats < 4) {
9097 changes = performLayoutLockedInner();
9098 if (changes != 0) {
9099 continue;
9100 }
9101 } else {
9102 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9103 changes = 0;
9104 }
9105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 final int transactionSequence = ++mTransactionSequence;
9107
9108 // Update animations of all applications, including those
9109 // associated with exiting/removed apps
9110 boolean tokensAnimating = false;
9111 final int NAT = mAppTokens.size();
9112 for (i=0; i<NAT; i++) {
9113 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9114 tokensAnimating = true;
9115 }
9116 }
9117 final int NEAT = mExitingAppTokens.size();
9118 for (i=0; i<NEAT; i++) {
9119 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9120 tokensAnimating = true;
9121 }
9122 }
9123
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009124 // SECOND LOOP: Execute animations and update visibility of windows.
9125
Joe Onorato8a9b2202010-02-26 18:56:32 -08009126 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009127 + transactionSequence + " tokensAnimating="
9128 + tokensAnimating);
9129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009130 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009131
9132 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009133 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009134 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009135
9136 mPolicy.beginAnimationLw(dw, dh);
9137
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009138 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009140 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009141 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142
9143 final WindowManager.LayoutParams attrs = w.mAttrs;
9144
9145 if (w.mSurface != null) {
9146 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009147 if (w.commitFinishDrawingLocked(currentTime)) {
9148 if ((w.mAttrs.flags
9149 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009150 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009151 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009152 wallpaperMayChange = true;
9153 }
9154 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009155
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009156 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009157 if (w.stepAnimationLocked(currentTime, dw, dh)) {
9158 animating = true;
9159 //w.dump(" ");
9160 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009161 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9162 wallpaperMayChange = true;
9163 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009164
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009165 if (mPolicy.doesForceHide(w, attrs)) {
9166 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009167 if (DEBUG_VISIBILITY) Slog.v(TAG,
9168 "Animation done that could impact force hide: "
9169 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009170 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009171 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009172 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9173 forceHiding = true;
9174 }
9175 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9176 boolean changed;
9177 if (forceHiding) {
9178 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009179 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9180 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009181 } else {
9182 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009183 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9184 "Now policy shown: " + w);
9185 if (changed) {
9186 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009187 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009188 // Assume we will need to animate. If
9189 // we don't (because the wallpaper will
9190 // stay with the lock screen), then we will
9191 // clean up later.
9192 Animation a = mPolicy.createForceHideEnterAnimation();
9193 if (a != null) {
9194 w.setAnimation(a);
9195 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009196 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009197 if (mCurrentFocus == null ||
9198 mCurrentFocus.mLayer < w.mLayer) {
9199 // We are showing on to of the current
9200 // focus, so re-evaluate focus to make
9201 // sure it is correct.
9202 mFocusMayChange = true;
9203 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009204 }
9205 }
9206 if (changed && (attrs.flags
9207 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9208 wallpaperMayChange = true;
9209 }
9210 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 mPolicy.animatingWindowLw(w, attrs);
9213 }
9214
9215 final AppWindowToken atoken = w.mAppToken;
9216 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9217 if (atoken.lastTransactionSequence != transactionSequence) {
9218 atoken.lastTransactionSequence = transactionSequence;
9219 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9220 atoken.startingDisplayed = false;
9221 }
9222 if ((w.isOnScreen() || w.mAttrs.type
9223 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9224 && !w.mExiting && !w.mDestroying) {
9225 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009226 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009227 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009228 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009229 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009230 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009231 + " pv=" + w.mPolicyVisibility
9232 + " dp=" + w.mDrawPending
9233 + " cdp=" + w.mCommitDrawPending
9234 + " ah=" + w.mAttachedHidden
9235 + " th=" + atoken.hiddenRequested
9236 + " a=" + w.mAnimating);
9237 }
9238 }
9239 if (w != atoken.startingWindow) {
9240 if (!atoken.freezingScreen || !w.mAppFreezing) {
9241 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009242 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009243 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009244 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009245 "tokenMayBeDrawn: " + atoken
9246 + " freezingScreen=" + atoken.freezingScreen
9247 + " mAppFreezing=" + w.mAppFreezing);
9248 tokenMayBeDrawn = true;
9249 }
9250 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009251 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 atoken.startingDisplayed = true;
9253 }
9254 }
9255 } else if (w.mReadyToShow) {
9256 w.performShowLocked();
9257 }
9258 }
9259
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009260 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261
9262 if (tokenMayBeDrawn) {
9263 // See if any windows have been drawn, so they (and others
9264 // associated with them) can now be shown.
9265 final int NT = mTokenList.size();
9266 for (i=0; i<NT; i++) {
9267 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9268 if (wtoken == null) {
9269 continue;
9270 }
9271 if (wtoken.freezingScreen) {
9272 int numInteresting = wtoken.numInterestingWindows;
9273 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009274 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009275 "allDrawn: " + wtoken
9276 + " interesting=" + numInteresting
9277 + " drawn=" + wtoken.numDrawnWindows);
9278 wtoken.showAllWindowsLocked();
9279 unsetAppFreezingScreenLocked(wtoken, false, true);
9280 orientationChangeComplete = true;
9281 }
9282 } else if (!wtoken.allDrawn) {
9283 int numInteresting = wtoken.numInterestingWindows;
9284 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009285 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009286 "allDrawn: " + wtoken
9287 + " interesting=" + numInteresting
9288 + " drawn=" + wtoken.numDrawnWindows);
9289 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009290 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009291
9292 // We can now show all of the drawn windows!
9293 if (!mOpeningApps.contains(wtoken)) {
9294 wtoken.showAllWindowsLocked();
9295 }
9296 }
9297 }
9298 }
9299 }
9300
9301 // If we are ready to perform an app transition, check through
9302 // all of the app tokens to be shown and see if they are ready
9303 // to go.
9304 if (mAppTransitionReady) {
9305 int NN = mOpeningApps.size();
9306 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009307 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009308 "Checking " + NN + " opening apps (frozen="
9309 + mDisplayFrozen + " timeout="
9310 + mAppTransitionTimeout + ")...");
9311 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9312 // If the display isn't frozen, wait to do anything until
9313 // all of the apps are ready. Otherwise just go because
9314 // we'll unfreeze the display when everyone is ready.
9315 for (i=0; i<NN && goodToGo; i++) {
9316 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009317 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 "Check opening app" + wtoken + ": allDrawn="
9319 + wtoken.allDrawn + " startingDisplayed="
9320 + wtoken.startingDisplayed);
9321 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9322 && !wtoken.startingMoved) {
9323 goodToGo = false;
9324 }
9325 }
9326 }
9327 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009328 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009329 int transit = mNextAppTransition;
9330 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009331 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009332 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009333 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009334 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009335 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 mAppTransitionTimeout = false;
9337 mStartingIconInTransition = false;
9338 mSkipAppTransitionAnimation = false;
9339
9340 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9341
Dianne Hackborna8f60182009-09-01 19:01:50 -07009342 // If there are applications waiting to come to the
9343 // top of the stack, now is the time to move their windows.
9344 // (Note that we don't do apps going to the bottom
9345 // here -- we want to keep their windows in the old
9346 // Z-order until the animation completes.)
9347 if (mToTopApps.size() > 0) {
9348 NN = mAppTokens.size();
9349 for (i=0; i<NN; i++) {
9350 AppWindowToken wtoken = mAppTokens.get(i);
9351 if (wtoken.sendingToTop) {
9352 wtoken.sendingToTop = false;
9353 moveAppWindowsLocked(wtoken, NN, false);
9354 }
9355 }
9356 mToTopApps.clear();
9357 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009358
Dianne Hackborn25994b42009-09-04 14:21:19 -07009359 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009360
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009361 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009362 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009363
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009364 // The top-most window will supply the layout params,
9365 // and we will determine it below.
9366 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009367 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009368 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009369
Joe Onorato8a9b2202010-02-26 18:56:32 -08009370 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009371 "New wallpaper target=" + mWallpaperTarget
9372 + ", lower target=" + mLowerWallpaperTarget
9373 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009374 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009375 // Do a first pass through the tokens for two
9376 // things:
9377 // (1) Determine if both the closing and opening
9378 // app token sets are wallpaper targets, in which
9379 // case special animations are needed
9380 // (since the wallpaper needs to stay static
9381 // behind them).
9382 // (2) Find the layout params of the top-most
9383 // application window in the tokens, which is
9384 // what will control the animation theme.
9385 final int NC = mClosingApps.size();
9386 NN = NC + mOpeningApps.size();
9387 for (i=0; i<NN; i++) {
9388 AppWindowToken wtoken;
9389 int mode;
9390 if (i < NC) {
9391 wtoken = mClosingApps.get(i);
9392 mode = 1;
9393 } else {
9394 wtoken = mOpeningApps.get(i-NC);
9395 mode = 2;
9396 }
9397 if (mLowerWallpaperTarget != null) {
9398 if (mLowerWallpaperTarget.mAppToken == wtoken
9399 || mUpperWallpaperTarget.mAppToken == wtoken) {
9400 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009401 }
9402 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009403 if (wtoken.appFullscreen) {
9404 WindowState ws = wtoken.findMainWindow();
9405 if (ws != null) {
9406 // If this is a compatibility mode
9407 // window, we will always use its anim.
9408 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9409 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009410 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009411 bestAnimLayer = Integer.MAX_VALUE;
9412 } else if (ws.mLayer > bestAnimLayer) {
9413 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009414 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009415 bestAnimLayer = ws.mLayer;
9416 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009417 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009418 }
9419 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009420
Dianne Hackborn25994b42009-09-04 14:21:19 -07009421 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009422 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009423 "Wallpaper animation!");
9424 switch (transit) {
9425 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9426 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9427 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9428 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9429 break;
9430 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9431 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9432 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9433 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9434 break;
9435 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009436 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009437 "New transit: " + transit);
9438 } else if (oldWallpaper != null) {
9439 // We are transitioning from an activity with
9440 // a wallpaper to one without.
9441 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009442 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009443 "New transit away from wallpaper: " + transit);
9444 } else if (mWallpaperTarget != null) {
9445 // We are transitioning from an activity without
9446 // a wallpaper to now showing the wallpaper
9447 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009448 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009449 "New transit into wallpaper: " + transit);
9450 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009451
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009452 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9453 mLastEnterAnimToken = animToken;
9454 mLastEnterAnimParams = animLp;
9455 } else if (mLastEnterAnimParams != null) {
9456 animLp = mLastEnterAnimParams;
9457 mLastEnterAnimToken = null;
9458 mLastEnterAnimParams = null;
9459 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009460
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009461 // If all closing windows are obscured, then there is
9462 // no need to do an animation. This is the case, for
9463 // example, when this transition is being done behind
9464 // the lock screen.
9465 if (!mPolicy.allowAppAnimationsLw()) {
9466 animLp = null;
9467 }
9468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469 NN = mOpeningApps.size();
9470 for (i=0; i<NN; i++) {
9471 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009472 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009473 "Now opening app" + wtoken);
9474 wtoken.reportedVisible = false;
9475 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009476 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009477 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009478 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009479 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009480 wtoken.showAllWindowsLocked();
9481 }
9482 NN = mClosingApps.size();
9483 for (i=0; i<NN; i++) {
9484 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009485 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009486 "Now closing app" + wtoken);
9487 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009488 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009489 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009491 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009492 // Force the allDrawn flag, because we want to start
9493 // this guy's animations regardless of whether it's
9494 // gotten drawn.
9495 wtoken.allDrawn = true;
9496 }
9497
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009498 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 mOpeningApps.clear();
9501 mClosingApps.clear();
9502
9503 // This has changed the visibility of windows, so perform
9504 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009505 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009506 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009507 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9508 assignLayersLocked();
9509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009511 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 }
9513 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009514
Dianne Hackborn16064f92010-03-25 00:47:24 -07009515 int adjResult = 0;
9516
Dianne Hackborna8f60182009-09-01 19:01:50 -07009517 if (!animating && mAppTransitionRunning) {
9518 // We have finished the animation of an app transition. To do
9519 // this, we have delayed a lot of operations like showing and
9520 // hiding apps, moving apps in Z-order, etc. The app token list
9521 // reflects the correct Z-order, but the window list may now
9522 // be out of sync with it. So here we will just rebuild the
9523 // entire app window list. Fun!
9524 mAppTransitionRunning = false;
9525 // Clear information about apps that were moving.
9526 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009527
Dianne Hackborna8f60182009-09-01 19:01:50 -07009528 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009529 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009530 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009531 moveInputMethodWindowsIfNeededLocked(false);
9532 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009533 // Since the window list has been rebuilt, focus might
9534 // have to be recomputed since the actual order of windows
9535 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009536 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009537 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009538
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009539 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009540 // At this point, there was a window with a wallpaper that
9541 // was force hiding other windows behind it, but now it
9542 // is going away. This may be simple -- just animate
9543 // away the wallpaper and its window -- or it may be
9544 // hard -- the wallpaper now needs to be shown behind
9545 // something that was hidden.
9546 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009547 if (mLowerWallpaperTarget != null
9548 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009549 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009550 "wallpaperForceHiding changed with lower="
9551 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009552 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009553 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
9554 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
9555 if (mLowerWallpaperTarget.mAppToken.hidden) {
9556 // The lower target has become hidden before we
9557 // actually started the animation... let's completely
9558 // re-evaluate everything.
9559 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009560 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009561 }
9562 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07009563 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009564 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009565 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009566 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009567 + " NEW: " + mWallpaperTarget
9568 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009569 if (mLowerWallpaperTarget == null) {
9570 // Whoops, we don't need a special wallpaper animation.
9571 // Clear them out.
9572 forceHiding = false;
9573 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009574 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009575 if (w.mSurface != null) {
9576 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07009577 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009578 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009579 forceHiding = true;
9580 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9581 if (!w.mAnimating) {
9582 // We set the animation above so it
9583 // is not yet running.
9584 w.clearAnimation();
9585 }
9586 }
9587 }
9588 }
9589 }
9590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009591
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009592 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009593 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009594 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07009595 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009596 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009597
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009598 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009599 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009600 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009601 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009602 assignLayersLocked();
9603 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009604 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009605 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009606 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009607 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009608
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009609 if (mFocusMayChange) {
9610 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009611 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009612 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009613 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009614 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009615 }
9616
9617 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009618 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009619 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009620
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009621 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
9622 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009623
Jeff Browne33348b2010-07-15 23:54:05 -07009624 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009625 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009626
9627 // THIRD LOOP: Update the surfaces of all windows.
9628
9629 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9630
9631 boolean obscured = false;
9632 boolean blurring = false;
9633 boolean dimming = false;
9634 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009635 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009636 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009638 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009640 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009641 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009642
9643 boolean displayed = false;
9644 final WindowManager.LayoutParams attrs = w.mAttrs;
9645 final int attrFlags = attrs.flags;
9646
9647 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009648 // XXX NOTE: The logic here could be improved. We have
9649 // the decision about whether to resize a window separated
9650 // from whether to hide the surface. This can cause us to
9651 // resize a surface even if we are going to hide it. You
9652 // can see this by (1) holding device in landscape mode on
9653 // home screen; (2) tapping browser icon (device will rotate
9654 // to landscape; (3) tap home. The wallpaper will be resized
9655 // in step 2 but then immediately hidden, causing us to
9656 // have to resize and then redraw it again in step 3. It
9657 // would be nice to figure out how to avoid this, but it is
9658 // difficult because we do need to resize surfaces in some
9659 // cases while they are hidden such as when first showing a
9660 // window.
9661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009662 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009663 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664 TAG, "Placing surface #" + i + " " + w.mSurface
9665 + ": new=" + w.mShownFrame + ", old="
9666 + w.mLastShownFrame);
9667
9668 boolean resize;
9669 int width, height;
9670 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9671 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9672 w.mLastRequestedHeight != w.mRequestedHeight;
9673 // for a scaled surface, we just want to use
9674 // the requested size.
9675 width = w.mRequestedWidth;
9676 height = w.mRequestedHeight;
9677 w.mLastRequestedWidth = width;
9678 w.mLastRequestedHeight = height;
9679 w.mLastShownFrame.set(w.mShownFrame);
9680 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009681 if (SHOW_TRANSACTIONS) logSurface(w,
9682 "POS " + w.mShownFrame.left
9683 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009684 w.mSurfaceX = w.mShownFrame.left;
9685 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9687 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009688 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009689 if (!recoveringMemory) {
9690 reclaimSomeSurfaceMemoryLocked(w, "position");
9691 }
9692 }
9693 } else {
9694 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9695 width = w.mShownFrame.width();
9696 height = w.mShownFrame.height();
9697 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 }
9699
9700 if (resize) {
9701 if (width < 1) width = 1;
9702 if (height < 1) height = 1;
9703 if (w.mSurface != null) {
9704 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009705 if (SHOW_TRANSACTIONS) logSurface(w,
9706 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009707 + w.mShownFrame.top + " SIZE "
9708 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009709 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009710 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009711 w.mSurfaceW = width;
9712 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009714 w.mSurfaceX = w.mShownFrame.left;
9715 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009716 w.mSurface.setPosition(w.mShownFrame.left,
9717 w.mShownFrame.top);
9718 } catch (RuntimeException e) {
9719 // If something goes wrong with the surface (such
9720 // as running out of memory), don't take down the
9721 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009722 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009723 + "size=(" + width + "x" + height
9724 + "), pos=(" + w.mShownFrame.left
9725 + "," + w.mShownFrame.top + ")", e);
9726 if (!recoveringMemory) {
9727 reclaimSomeSurfaceMemoryLocked(w, "size");
9728 }
9729 }
9730 }
9731 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009732 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009733 w.mContentInsetsChanged =
9734 !w.mLastContentInsets.equals(w.mContentInsets);
9735 w.mVisibleInsetsChanged =
9736 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009737 boolean configChanged =
9738 w.mConfiguration != mCurConfiguration
9739 && (w.mConfiguration == null
9740 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009741 if (DEBUG_CONFIGURATION && configChanged) {
9742 Slog.v(TAG, "Win " + w + " config changed: "
9743 + mCurConfiguration);
9744 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009745 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009746 + ": configChanged=" + configChanged
9747 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -07009748 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009749 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009750 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009751 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009752 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009753 w.mLastFrame.set(w.mFrame);
9754 w.mLastContentInsets.set(w.mContentInsets);
9755 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009756 // If the screen is currently frozen, then keep
9757 // it frozen until this window draws at its new
9758 // orientation.
9759 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009760 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009761 "Resizing while display frozen: " + w);
9762 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009763 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009764 mWindowsFreezingScreen = true;
9765 // XXX should probably keep timeout from
9766 // when we first froze the display.
9767 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9768 mH.sendMessageDelayed(mH.obtainMessage(
9769 H.WINDOW_FREEZE_TIMEOUT), 2000);
9770 }
9771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 // If the orientation is changing, then we need to
9773 // hold off on unfreezing the display until this
9774 // window has been redrawn; to do that, we need
9775 // to go through the process of getting informed
9776 // by the application when it has finished drawing.
9777 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009778 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009779 "Orientation start waiting for draw in "
9780 + w + ", surface " + w.mSurface);
9781 w.mDrawPending = true;
9782 w.mCommitDrawPending = false;
9783 w.mReadyToShow = false;
9784 if (w.mAppToken != null) {
9785 w.mAppToken.allDrawn = false;
9786 }
9787 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009788 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009789 "Resizing window " + w + " to " + w.mFrame);
9790 mResizingWindows.add(w);
9791 } else if (w.mOrientationChanging) {
9792 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009793 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 "Orientation not waiting for draw in "
9795 + w + ", surface " + w.mSurface);
9796 w.mOrientationChanging = false;
9797 }
9798 }
9799 }
9800
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009801 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 if (!w.mLastHidden) {
9803 //dump();
9804 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009805 if (SHOW_TRANSACTIONS) logSurface(w,
9806 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009808 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009809 try {
9810 w.mSurface.hide();
9811 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009812 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813 }
9814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 }
9816 // If we are waiting for this window to handle an
9817 // orientation change, well, it is hidden, so
9818 // doesn't really matter. Note that this does
9819 // introduce a potential glitch if the window
9820 // becomes unhidden before it has drawn for the
9821 // new orientation.
9822 if (w.mOrientationChanging) {
9823 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009824 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 "Orientation change skips hidden " + w);
9826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009827 } else if (w.mLastLayer != w.mAnimLayer
9828 || w.mLastAlpha != w.mShownAlpha
9829 || w.mLastDsDx != w.mDsDx
9830 || w.mLastDtDx != w.mDtDx
9831 || w.mLastDsDy != w.mDsDy
9832 || w.mLastDtDy != w.mDtDy
9833 || w.mLastHScale != w.mHScale
9834 || w.mLastVScale != w.mVScale
9835 || w.mLastHidden) {
9836 displayed = true;
9837 w.mLastAlpha = w.mShownAlpha;
9838 w.mLastLayer = w.mAnimLayer;
9839 w.mLastDsDx = w.mDsDx;
9840 w.mLastDtDx = w.mDtDx;
9841 w.mLastDsDy = w.mDsDy;
9842 w.mLastDtDy = w.mDtDy;
9843 w.mLastHScale = w.mHScale;
9844 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009845 if (SHOW_TRANSACTIONS) logSurface(w,
9846 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009847 + " matrix=[" + (w.mDsDx*w.mHScale)
9848 + "," + (w.mDtDx*w.mVScale)
9849 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009850 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 if (w.mSurface != null) {
9852 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009853 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009855 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 w.mSurface.setLayer(w.mAnimLayer);
9857 w.mSurface.setMatrix(
9858 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
9859 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
9860 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009861 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 if (!recoveringMemory) {
9863 reclaimSomeSurfaceMemoryLocked(w, "update");
9864 }
9865 }
9866 }
9867
9868 if (w.mLastHidden && !w.mDrawPending
9869 && !w.mCommitDrawPending
9870 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009871 if (SHOW_TRANSACTIONS) logSurface(w,
9872 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009873 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874 + " during relayout");
9875 if (showSurfaceRobustlyLocked(w)) {
9876 w.mHasDrawn = true;
9877 w.mLastHidden = false;
9878 } else {
9879 w.mOrientationChanging = false;
9880 }
9881 }
9882 if (w.mSurface != null) {
9883 w.mToken.hasVisible = true;
9884 }
9885 } else {
9886 displayed = true;
9887 }
9888
9889 if (displayed) {
9890 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08009891 if (attrs.width == LayoutParams.MATCH_PARENT
9892 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 covered = true;
9894 }
9895 }
9896 if (w.mOrientationChanging) {
9897 if (w.mDrawPending || w.mCommitDrawPending) {
9898 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009899 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009900 "Orientation continue waiting for draw in " + w);
9901 } else {
9902 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009903 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009904 "Orientation change complete in " + w);
9905 }
9906 }
9907 w.mToken.hasVisible = true;
9908 }
9909 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009910 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 "Orientation change skips hidden " + w);
9912 w.mOrientationChanging = false;
9913 }
9914
9915 final boolean canBeSeen = w.isDisplayedLw();
9916
9917 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
9918 focusDisplayed = true;
9919 }
9920
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07009921 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009924 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 if (w.mSurface != null) {
9926 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
9927 holdScreen = w.mSession;
9928 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009929 if (!syswin && w.mAttrs.screenBrightness >= 0
9930 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 screenBrightness = w.mAttrs.screenBrightness;
9932 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009933 if (!syswin && w.mAttrs.buttonBrightness >= 0
9934 && buttonBrightness < 0) {
9935 buttonBrightness = w.mAttrs.buttonBrightness;
9936 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05009937 if (canBeSeen
9938 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
9939 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
9940 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009941 syswin = true;
9942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009944
Dianne Hackborn25994b42009-09-04 14:21:19 -07009945 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
9946 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009947 // This window completely covers everything behind it,
9948 // so we want to leave all of them as unblurred (for
9949 // performance reasons).
9950 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009951 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009952 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009953 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009954 obscured = true;
9955 if (mBackgroundFillerSurface == null) {
9956 try {
9957 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009958 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009959 0, dw, dh,
9960 PixelFormat.OPAQUE,
9961 Surface.FX_SURFACE_NORMAL);
9962 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009963 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009964 }
9965 }
9966 try {
9967 mBackgroundFillerSurface.setPosition(0, 0);
9968 mBackgroundFillerSurface.setSize(dw, dh);
9969 // Using the same layer as Dim because they will never be shown at the
9970 // same time.
9971 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
9972 mBackgroundFillerSurface.show();
9973 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009974 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009975 }
9976 backgroundFillerShown = true;
9977 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009978 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009980 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 + ": blurring=" + blurring
9982 + " obscured=" + obscured
9983 + " displayed=" + displayed);
9984 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
9985 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009986 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009988 if (mDimAnimator == null) {
9989 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009991 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009992 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009994 }
9995 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
9996 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009997 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010000 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010001 + mBlurSurface + ": CREATE");
10002 try {
Romain Guy06882f82009-06-10 13:36:04 -070010003 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010004 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 -1, 16, 16,
10006 PixelFormat.OPAQUE,
10007 Surface.FX_SURFACE_BLUR);
10008 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010009 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010 }
10011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010013 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10014 + mBlurSurface + ": pos=(0,0) (" +
10015 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 mBlurSurface.setPosition(0, 0);
10017 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010018 mBlurSurface.setLayer(w.mAnimLayer-2);
10019 if (!mBlurShown) {
10020 try {
10021 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10022 + mBlurSurface + ": SHOW");
10023 mBlurSurface.show();
10024 } catch (RuntimeException e) {
10025 Slog.w(TAG, "Failure showing blur surface", e);
10026 }
10027 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028 }
10029 }
10030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010031 }
10032 }
10033 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010034
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010035 if (obscuredChanged && mWallpaperTarget == w) {
10036 // This is the wallpaper target and its obscured state
10037 // changed... make sure the current wallaper's visibility
10038 // has been updated accordingly.
10039 updateWallpaperVisibilityLocked();
10040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010041 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010042
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010043 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10044 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010045 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010046 try {
10047 mBackgroundFillerSurface.hide();
10048 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010049 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010050 }
10051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010053 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010054 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10055 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010056 }
Romain Guy06882f82009-06-10 13:36:04 -070010057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010059 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010060 + ": HIDE");
10061 try {
10062 mBlurSurface.hide();
10063 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010064 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 }
10066 mBlurShown = false;
10067 }
10068
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010071 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 }
10073
Jeff Browne33348b2010-07-15 23:54:05 -070010074 mInputMonitor.updateInputWindowsLw();
10075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010077
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010078 if (mWatermark != null) {
10079 mWatermark.drawIfNeeded();
10080 }
10081
Joe Onorato8a9b2202010-02-26 18:56:32 -080010082 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 "With display frozen, orientationChangeComplete="
10084 + orientationChangeComplete);
10085 if (orientationChangeComplete) {
10086 if (mWindowsFreezingScreen) {
10087 mWindowsFreezingScreen = false;
10088 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10089 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010090 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 }
Romain Guy06882f82009-06-10 13:36:04 -070010092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010093 i = mResizingWindows.size();
10094 if (i > 0) {
10095 do {
10096 i--;
10097 WindowState win = mResizingWindows.get(i);
10098 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010099 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10100 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010101 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010102 boolean configChanged =
10103 win.mConfiguration != mCurConfiguration
10104 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010105 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10106 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10107 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010108 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010109 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010110 + " / " + mCurConfiguration + " / 0x"
10111 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010112 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010113 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114 win.mClient.resized(win.mFrame.width(),
10115 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010116 win.mLastVisibleInsets, win.mDrawPending,
10117 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 win.mContentInsetsChanged = false;
10119 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010120 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 } catch (RemoteException e) {
10122 win.mOrientationChanging = false;
10123 }
10124 } while (i > 0);
10125 mResizingWindows.clear();
10126 }
Romain Guy06882f82009-06-10 13:36:04 -070010127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010128 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010129 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130 i = mDestroySurface.size();
10131 if (i > 0) {
10132 do {
10133 i--;
10134 WindowState win = mDestroySurface.get(i);
10135 win.mDestroying = false;
10136 if (mInputMethodWindow == win) {
10137 mInputMethodWindow = null;
10138 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010139 if (win == mWallpaperTarget) {
10140 wallpaperDestroyed = true;
10141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010142 win.destroySurfaceLocked();
10143 } while (i > 0);
10144 mDestroySurface.clear();
10145 }
10146
10147 // Time to remove any exiting tokens?
10148 for (i=mExitingTokens.size()-1; i>=0; i--) {
10149 WindowToken token = mExitingTokens.get(i);
10150 if (!token.hasVisible) {
10151 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010152 if (token.windowType == TYPE_WALLPAPER) {
10153 mWallpaperTokens.remove(token);
10154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010155 }
10156 }
10157
10158 // Time to remove any exiting applications?
10159 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10160 AppWindowToken token = mExitingAppTokens.get(i);
10161 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010162 // Make sure there is no animation running on this token,
10163 // so any windows associated with it will be removed as
10164 // soon as their animations are complete
10165 token.animation = null;
10166 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 mAppTokens.remove(token);
10168 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010169 if (mLastEnterAnimToken == token) {
10170 mLastEnterAnimToken = null;
10171 mLastEnterAnimParams = null;
10172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010173 }
10174 }
10175
Dianne Hackborna8f60182009-09-01 19:01:50 -070010176 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010177
Dianne Hackborna8f60182009-09-01 19:01:50 -070010178 if (!animating && mAppTransitionRunning) {
10179 // We have finished the animation of an app transition. To do
10180 // this, we have delayed a lot of operations like showing and
10181 // hiding apps, moving apps in Z-order, etc. The app token list
10182 // reflects the correct Z-order, but the window list may now
10183 // be out of sync with it. So here we will just rebuild the
10184 // entire app window list. Fun!
10185 mAppTransitionRunning = false;
10186 needRelayout = true;
10187 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010188 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010189 // Clear information about apps that were moving.
10190 mToBottomApps.clear();
10191 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 if (focusDisplayed) {
10194 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10195 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010196 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010197 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010198 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010199 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010200 requestAnimationLocked(0);
10201 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10203 }
Jeff Browneb857f12010-07-16 10:06:33 -070010204
Jeff Browne33348b2010-07-15 23:54:05 -070010205 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010206
Jeff Brown8e03b752010-06-13 19:16:55 -070010207 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10209 mPowerManager.setScreenBrightnessOverride(-1);
10210 } else {
10211 mPowerManager.setScreenBrightnessOverride((int)
10212 (screenBrightness * Power.BRIGHTNESS_ON));
10213 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010214 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10215 mPowerManager.setButtonBrightnessOverride(-1);
10216 } else {
10217 mPowerManager.setButtonBrightnessOverride((int)
10218 (buttonBrightness * Power.BRIGHTNESS_ON));
10219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010220 if (holdScreen != mHoldingScreenOn) {
10221 mHoldingScreenOn = holdScreen;
10222 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10223 mH.sendMessage(m);
10224 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010225
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010226 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010227 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010228 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10229 LocalPowerManager.BUTTON_EVENT, true);
10230 mTurnOnScreen = false;
10231 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010232
10233 // Check to see if we are now in a state where the screen should
10234 // be enabled, because the window obscured flags have changed.
10235 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010236 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010237
10238 /**
10239 * Must be called with the main window manager lock held.
10240 */
10241 void setHoldScreenLocked(boolean holding) {
10242 boolean state = mHoldingScreenWakeLock.isHeld();
10243 if (holding != state) {
10244 if (holding) {
10245 mHoldingScreenWakeLock.acquire();
10246 } else {
10247 mPolicy.screenOnStoppedLw();
10248 mHoldingScreenWakeLock.release();
10249 }
10250 }
10251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252
10253 void requestAnimationLocked(long delay) {
10254 if (!mAnimationPending) {
10255 mAnimationPending = true;
10256 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10257 }
10258 }
Romain Guy06882f82009-06-10 13:36:04 -070010259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260 /**
10261 * Have the surface flinger show a surface, robustly dealing with
10262 * error conditions. In particular, if there is not enough memory
10263 * to show the surface, then we will try to get rid of other surfaces
10264 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010265 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 * @return Returns true if the surface was successfully shown.
10267 */
10268 boolean showSurfaceRobustlyLocked(WindowState win) {
10269 try {
10270 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010271 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010272 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010273 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010274 if (DEBUG_VISIBILITY) Slog.v(TAG,
10275 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010276 win.mTurnOnScreen = false;
10277 mTurnOnScreen = true;
10278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 }
10280 return true;
10281 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010282 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010283 }
Romain Guy06882f82009-06-10 13:36:04 -070010284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 return false;
10288 }
Romain Guy06882f82009-06-10 13:36:04 -070010289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10291 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010292
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010293 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 if (mForceRemoves == null) {
10297 mForceRemoves = new ArrayList<WindowState>();
10298 }
Romain Guy06882f82009-06-10 13:36:04 -070010299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 long callingIdentity = Binder.clearCallingIdentity();
10301 try {
10302 // There was some problem... first, do a sanity check of the
10303 // window list to make sure we haven't left any dangling surfaces
10304 // around.
10305 int N = mWindows.size();
10306 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010307 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010309 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010310 if (ws.mSurface != null) {
10311 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010312 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010313 + ws + " surface=" + ws.mSurface
10314 + " token=" + win.mToken
10315 + " pid=" + ws.mSession.mPid
10316 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010317 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010318 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 ws.mSurface = null;
10320 mForceRemoves.add(ws);
10321 i--;
10322 N--;
10323 leakedSurface = true;
10324 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010325 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 + ws + " surface=" + ws.mSurface
10327 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010328 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010329 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 ws.mSurface = null;
10331 leakedSurface = true;
10332 }
10333 }
10334 }
Romain Guy06882f82009-06-10 13:36:04 -070010335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 boolean killedApps = false;
10337 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010338 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339 SparseIntArray pidCandidates = new SparseIntArray();
10340 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010341 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010342 if (ws.mSurface != null) {
10343 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10344 }
10345 }
10346 if (pidCandidates.size() > 0) {
10347 int[] pids = new int[pidCandidates.size()];
10348 for (int i=0; i<pids.length; i++) {
10349 pids[i] = pidCandidates.keyAt(i);
10350 }
10351 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010352 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 killedApps = true;
10354 }
10355 } catch (RemoteException e) {
10356 }
10357 }
10358 }
Romain Guy06882f82009-06-10 13:36:04 -070010359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010360 if (leakedSurface || killedApps) {
10361 // We managed to reclaim some memory, so get rid of the trouble
10362 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010363 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010364 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010365 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010366 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010367 win.mSurface = null;
10368 }
Romain Guy06882f82009-06-10 13:36:04 -070010369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370 try {
10371 win.mClient.dispatchGetNewSurface();
10372 } catch (RemoteException e) {
10373 }
10374 }
10375 } finally {
10376 Binder.restoreCallingIdentity(callingIdentity);
10377 }
10378 }
Romain Guy06882f82009-06-10 13:36:04 -070010379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010380 private boolean updateFocusedWindowLocked(int mode) {
10381 WindowState newFocus = computeFocusedWindowLocked();
10382 if (mCurrentFocus != newFocus) {
10383 // This check makes sure that we don't already have the focus
10384 // change message pending.
10385 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10386 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010387 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010388 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10389 final WindowState oldFocus = mCurrentFocus;
10390 mCurrentFocus = newFocus;
10391 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010393 final WindowState imWindow = mInputMethodWindow;
10394 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010395 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010396 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010397 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10398 mLayoutNeeded = true;
10399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010400 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
10401 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010402 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10403 // Client will do the layout, but we need to assign layers
10404 // for handleNewWindowLocked() below.
10405 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 }
10407 }
Jeff Brown349703e2010-06-22 01:27:15 -070010408
10409 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10410 // If we defer assigning layers, then the caller is responsible for
10411 // doing this part.
10412 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010414 return true;
10415 }
10416 return false;
10417 }
Jeff Brown349703e2010-06-22 01:27:15 -070010418
10419 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010420 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010422
10423 private WindowState computeFocusedWindowLocked() {
10424 WindowState result = null;
10425 WindowState win;
10426
10427 int i = mWindows.size() - 1;
10428 int nextAppIndex = mAppTokens.size()-1;
10429 WindowToken nextApp = nextAppIndex >= 0
10430 ? mAppTokens.get(nextAppIndex) : null;
10431
10432 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010433 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434
Joe Onorato8a9b2202010-02-26 18:56:32 -080010435 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 TAG, "Looking for focus: " + i
10437 + " = " + win
10438 + ", flags=" + win.mAttrs.flags
10439 + ", canReceive=" + win.canReceiveKeys());
10440
10441 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 // If this window's application has been removed, just skip it.
10444 if (thisApp != null && thisApp.removed) {
10445 i--;
10446 continue;
10447 }
Romain Guy06882f82009-06-10 13:36:04 -070010448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 // If there is a focused app, don't allow focus to go to any
10450 // windows below it. If this is an application window, step
10451 // through the app tokens until we find its app.
10452 if (thisApp != null && nextApp != null && thisApp != nextApp
10453 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10454 int origAppIndex = nextAppIndex;
10455 while (nextAppIndex > 0) {
10456 if (nextApp == mFocusedApp) {
10457 // Whoops, we are below the focused app... no focus
10458 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010459 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010460 TAG, "Reached focused app: " + mFocusedApp);
10461 return null;
10462 }
10463 nextAppIndex--;
10464 nextApp = mAppTokens.get(nextAppIndex);
10465 if (nextApp == thisApp) {
10466 break;
10467 }
10468 }
10469 if (thisApp != nextApp) {
10470 // Uh oh, the app token doesn't exist! This shouldn't
10471 // happen, but if it does we can get totally hosed...
10472 // so restart at the original app.
10473 nextAppIndex = origAppIndex;
10474 nextApp = mAppTokens.get(nextAppIndex);
10475 }
10476 }
10477
10478 // Dispatch to this window if it is wants key events.
10479 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010480 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010481 TAG, "Found focus @ " + i + " = " + win);
10482 result = win;
10483 break;
10484 }
10485
10486 i--;
10487 }
10488
10489 return result;
10490 }
10491
10492 private void startFreezingDisplayLocked() {
10493 if (mDisplayFrozen) {
10494 return;
10495 }
Romain Guy06882f82009-06-10 13:36:04 -070010496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010497 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010499 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010500 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 if (mFreezeGcPending != 0) {
10502 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010503 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010504 mH.removeMessages(H.FORCE_GC);
10505 Runtime.getRuntime().gc();
10506 mFreezeGcPending = now;
10507 }
10508 } else {
10509 mFreezeGcPending = now;
10510 }
Romain Guy06882f82009-06-10 13:36:04 -070010511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010512 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010513
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010514 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010515
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010516 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10517 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010518 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010519 mAppTransitionReady = true;
10520 }
Romain Guy06882f82009-06-10 13:36:04 -070010521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 if (PROFILE_ORIENTATION) {
10523 File file = new File("/data/system/frozen");
10524 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10525 }
10526 Surface.freezeDisplay(0);
10527 }
Romain Guy06882f82009-06-10 13:36:04 -070010528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010529 private void stopFreezingDisplayLocked() {
10530 if (!mDisplayFrozen) {
10531 return;
10532 }
Romain Guy06882f82009-06-10 13:36:04 -070010533
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010534 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
10535 return;
10536 }
10537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010538 mDisplayFrozen = false;
10539 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
10540 if (PROFILE_ORIENTATION) {
10541 Debug.stopMethodTracing();
10542 }
10543 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070010544
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010545 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546
Christopher Tateb696aee2010-04-02 19:08:30 -070010547 // While the display is frozen we don't re-compute the orientation
10548 // to avoid inconsistent states. However, something interesting
10549 // could have actually changed during that time so re-evaluate it
10550 // now to catch that.
10551 if (updateOrientationFromAppTokensLocked()) {
10552 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10553 }
10554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 // A little kludge: a lot could have happened while the
10556 // display was frozen, so now that we are coming back we
10557 // do a gc so that any remote references the system
10558 // processes holds on others can be released if they are
10559 // no longer needed.
10560 mH.removeMessages(H.FORCE_GC);
10561 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10562 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010564 mScreenFrozenLock.release();
10565 }
Romain Guy06882f82009-06-10 13:36:04 -070010566
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010567 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10568 DisplayMetrics dm) {
10569 if (index < tokens.length) {
10570 String str = tokens[index];
10571 if (str != null && str.length() > 0) {
10572 try {
10573 int val = Integer.parseInt(str);
10574 return val;
10575 } catch (Exception e) {
10576 }
10577 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010578 }
10579 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10580 return defDps;
10581 }
10582 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10583 return val;
10584 }
10585
10586 class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010587 final String[] mTokens;
10588 final String mText;
10589 final Paint mTextPaint;
10590 final int mTextWidth;
10591 final int mTextHeight;
10592 final int mTextAscent;
10593 final int mTextDescent;
10594 final int mDeltaX;
10595 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010596
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010597 Surface mSurface;
10598 int mLastDW;
10599 int mLastDH;
10600 boolean mDrawNeeded;
10601
10602 Watermark(SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010603 final DisplayMetrics dm = new DisplayMetrics();
10604 mDisplay.getMetrics(dm);
10605
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010606 if (false) {
10607 Log.i(TAG, "*********************** WATERMARK");
10608 for (int i=0; i<tokens.length; i++) {
10609 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
10610 }
10611 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010612
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010613 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010614
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010615 StringBuilder builder = new StringBuilder(32);
10616 int len = mTokens[0].length();
10617 len = len & ~1;
10618 for (int i=0; i<len; i+=2) {
10619 int c1 = mTokens[0].charAt(i);
10620 int c2 = mTokens[0].charAt(i+1);
10621 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
10622 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
10623 else c1 -= '0';
10624 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
10625 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
10626 else c2 -= '0';
10627 builder.append((char)(255-((c1*16)+c2)));
10628 }
10629 mText = builder.toString();
10630 if (false) {
10631 Log.i(TAG, "Final text: " + mText);
10632 }
10633
10634 int fontSize = getPropertyInt(tokens, 1,
10635 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
10636
10637 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
10638 mTextPaint.setTextSize(fontSize);
10639 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
10640
10641 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
10642 mTextWidth = (int)mTextPaint.measureText(mText);
10643 mTextAscent = fm.ascent;
10644 mTextDescent = fm.descent;
10645 mTextHeight = fm.descent - fm.ascent;
10646
10647 mDeltaX = getPropertyInt(tokens, 2,
10648 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
10649 mDeltaY = getPropertyInt(tokens, 3,
10650 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
10651 int shadowColor = getPropertyInt(tokens, 4,
10652 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
10653 int color = getPropertyInt(tokens, 5,
10654 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
10655 int shadowRadius = getPropertyInt(tokens, 6,
10656 TypedValue.COMPLEX_UNIT_PX, 7, dm);
10657 int shadowDx = getPropertyInt(tokens, 8,
10658 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10659 int shadowDy = getPropertyInt(tokens, 9,
10660 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10661
10662 mTextPaint.setColor(color);
10663 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010664
10665 try {
10666 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010667 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010668 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010669 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010670 mSurface.show();
10671 } catch (OutOfResourcesException e) {
10672 }
10673 }
10674
10675 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010676 if (mLastDW != dw || mLastDH != dh) {
10677 mLastDW = dw;
10678 mLastDH = dh;
10679 mSurface.setSize(dw, dh);
10680 mDrawNeeded = true;
10681 }
10682 }
10683
10684 void drawIfNeeded() {
10685 if (mDrawNeeded) {
10686 final int dw = mLastDW;
10687 final int dh = mLastDH;
10688
10689 mDrawNeeded = false;
10690 Rect dirty = new Rect(0, 0, dw, dh);
10691 Canvas c = null;
10692 try {
10693 c = mSurface.lockCanvas(dirty);
10694 } catch (IllegalArgumentException e) {
10695 } catch (OutOfResourcesException e) {
10696 }
10697 if (c != null) {
10698 int deltaX = mDeltaX;
10699 int deltaY = mDeltaY;
10700
10701 // deltaX shouldn't be close to a round fraction of our
10702 // x step, or else things will line up too much.
10703 int div = (dw+mTextWidth)/deltaX;
10704 int rem = (dw+mTextWidth) - (div*deltaX);
10705 int qdelta = deltaX/4;
10706 if (rem < qdelta || rem > (deltaX-qdelta)) {
10707 deltaX += deltaX/3;
10708 }
10709
10710 int y = -mTextHeight;
10711 int x = -mTextWidth;
10712 while (y < (dh+mTextHeight)) {
10713 c.drawText(mText, x, y, mTextPaint);
10714 x += deltaX;
10715 if (x >= dw) {
10716 x -= (dw+mTextWidth);
10717 y += deltaY;
10718 }
10719 }
10720 mSurface.unlockCanvasAndPost(c);
10721 }
10722 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010723 }
10724 }
10725
10726 void createWatermark() {
10727 if (mWatermark != null) {
10728 return;
10729 }
10730
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010731 File file = new File("/system/etc/setup.conf");
10732 FileInputStream in = null;
10733 try {
10734 in = new FileInputStream(file);
10735 DataInputStream ind = new DataInputStream(in);
10736 String line = ind.readLine();
10737 if (line != null) {
10738 String[] toks = line.split("%");
10739 if (toks != null && toks.length > 0) {
10740 mWatermark = new Watermark(mFxSession, toks);
10741 }
10742 }
10743 } catch (FileNotFoundException e) {
10744 } catch (IOException e) {
10745 } finally {
10746 if (in != null) {
10747 try {
10748 in.close();
10749 } catch (IOException e) {
10750 }
10751 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010752 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010753 }
10754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010755 @Override
10756 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10757 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10758 != PackageManager.PERMISSION_GRANTED) {
10759 pw.println("Permission Denial: can't dump WindowManager from from pid="
10760 + Binder.getCallingPid()
10761 + ", uid=" + Binder.getCallingUid());
10762 return;
10763 }
Romain Guy06882f82009-06-10 13:36:04 -070010764
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010765 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080010766 pw.println(" ");
10767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010768 synchronized(mWindowMap) {
10769 pw.println("Current Window Manager state:");
10770 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010771 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010772 pw.print(" Window #"); pw.print(i); pw.print(' ');
10773 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774 w.dump(pw, " ");
10775 }
10776 if (mInputMethodDialogs.size() > 0) {
10777 pw.println(" ");
10778 pw.println(" Input method dialogs:");
10779 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10780 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010781 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 }
10783 }
10784 if (mPendingRemove.size() > 0) {
10785 pw.println(" ");
10786 pw.println(" Remove pending for:");
10787 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10788 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010789 pw.print(" Remove #"); pw.print(i); pw.print(' ');
10790 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010791 w.dump(pw, " ");
10792 }
10793 }
10794 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10795 pw.println(" ");
10796 pw.println(" Windows force removing:");
10797 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10798 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010799 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10800 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010801 w.dump(pw, " ");
10802 }
10803 }
10804 if (mDestroySurface.size() > 0) {
10805 pw.println(" ");
10806 pw.println(" Windows waiting to destroy their surface:");
10807 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10808 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010809 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
10810 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010811 w.dump(pw, " ");
10812 }
10813 }
10814 if (mLosingFocus.size() > 0) {
10815 pw.println(" ");
10816 pw.println(" Windows losing focus:");
10817 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10818 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010819 pw.print(" Losing #"); pw.print(i); pw.print(' ');
10820 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010821 w.dump(pw, " ");
10822 }
10823 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010824 if (mResizingWindows.size() > 0) {
10825 pw.println(" ");
10826 pw.println(" Windows waiting to resize:");
10827 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10828 WindowState w = mResizingWindows.get(i);
10829 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
10830 pw.print(w); pw.println(":");
10831 w.dump(pw, " ");
10832 }
10833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834 if (mSessions.size() > 0) {
10835 pw.println(" ");
10836 pw.println(" All active sessions:");
10837 Iterator<Session> it = mSessions.iterator();
10838 while (it.hasNext()) {
10839 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010840 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 s.dump(pw, " ");
10842 }
10843 }
10844 if (mTokenMap.size() > 0) {
10845 pw.println(" ");
10846 pw.println(" All tokens:");
10847 Iterator<WindowToken> it = mTokenMap.values().iterator();
10848 while (it.hasNext()) {
10849 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010850 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 token.dump(pw, " ");
10852 }
10853 }
10854 if (mTokenList.size() > 0) {
10855 pw.println(" ");
10856 pw.println(" Window token list:");
10857 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010858 pw.print(" #"); pw.print(i); pw.print(": ");
10859 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 }
10861 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010862 if (mWallpaperTokens.size() > 0) {
10863 pw.println(" ");
10864 pw.println(" Wallpaper tokens:");
10865 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10866 WindowToken token = mWallpaperTokens.get(i);
10867 pw.print(" Wallpaper #"); pw.print(i);
10868 pw.print(' '); pw.print(token); pw.println(':');
10869 token.dump(pw, " ");
10870 }
10871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010872 if (mAppTokens.size() > 0) {
10873 pw.println(" ");
10874 pw.println(" Application tokens in Z order:");
10875 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010876 pw.print(" App #"); pw.print(i); pw.print(": ");
10877 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010878 }
10879 }
10880 if (mFinishedStarting.size() > 0) {
10881 pw.println(" ");
10882 pw.println(" Finishing start of application tokens:");
10883 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10884 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010885 pw.print(" Finished Starting #"); pw.print(i);
10886 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010887 token.dump(pw, " ");
10888 }
10889 }
10890 if (mExitingTokens.size() > 0) {
10891 pw.println(" ");
10892 pw.println(" Exiting tokens:");
10893 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10894 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010895 pw.print(" Exiting #"); pw.print(i);
10896 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010897 token.dump(pw, " ");
10898 }
10899 }
10900 if (mExitingAppTokens.size() > 0) {
10901 pw.println(" ");
10902 pw.println(" Exiting application tokens:");
10903 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10904 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010905 pw.print(" Exiting App #"); pw.print(i);
10906 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010907 token.dump(pw, " ");
10908 }
10909 }
10910 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010911 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10912 pw.print(" mLastFocus="); pw.println(mLastFocus);
10913 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10914 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
10915 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010916 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010917 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10918 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10919 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10920 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010921 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10922 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10923 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010924 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10925 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
10926 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
10927 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010928 if (mDimAnimator != null) {
10929 mDimAnimator.printTo(pw);
10930 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080010931 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010932 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010933 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070010934 pw.print(mInputMethodAnimLayerAdjustment);
10935 pw.print(" mWallpaperAnimLayerAdjustment=");
10936 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010937 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10938 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010939 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
10940 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010941 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
10942 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010943 pw.print(" mRotation="); pw.print(mRotation);
10944 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
10945 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
10946 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
10947 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10948 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
10949 pw.print(" mNextAppTransition=0x");
10950 pw.print(Integer.toHexString(mNextAppTransition));
10951 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070010952 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010953 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010954 if (mNextAppTransitionPackage != null) {
10955 pw.print(" mNextAppTransitionPackage=");
10956 pw.print(mNextAppTransitionPackage);
10957 pw.print(", mNextAppTransitionEnter=0x");
10958 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10959 pw.print(", mNextAppTransitionExit=0x");
10960 pw.print(Integer.toHexString(mNextAppTransitionExit));
10961 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010962 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
10963 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010964 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
10965 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
10966 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
10967 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010968 if (mOpeningApps.size() > 0) {
10969 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10970 }
10971 if (mClosingApps.size() > 0) {
10972 pw.print(" mClosingApps="); pw.println(mClosingApps);
10973 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010974 if (mToTopApps.size() > 0) {
10975 pw.print(" mToTopApps="); pw.println(mToTopApps);
10976 }
10977 if (mToBottomApps.size() > 0) {
10978 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
10979 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010980 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
10981 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 }
10983 }
10984
Jeff Brown349703e2010-06-22 01:27:15 -070010985 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 public void monitor() {
10987 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050010988 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010989 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010990
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010991 /**
10992 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010993 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010994 */
10995 private static class DimAnimator {
10996 Surface mDimSurface;
10997 boolean mDimShown = false;
10998 float mDimCurrentAlpha;
10999 float mDimTargetAlpha;
11000 float mDimDeltaPerMs;
11001 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011002
11003 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011004
11005 DimAnimator (SurfaceSession session) {
11006 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011007 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011008 + mDimSurface + ": CREATE");
11009 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011010 mDimSurface = new Surface(session, 0,
11011 "DimSurface",
11012 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011013 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011014 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011015 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011016 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011017 }
11018 }
11019 }
11020
11021 /**
11022 * Show the dim surface.
11023 */
11024 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011025 if (!mDimShown) {
11026 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11027 dw + "x" + dh + ")");
11028 mDimShown = true;
11029 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011030 mLastDimWidth = dw;
11031 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011032 mDimSurface.setPosition(0, 0);
11033 mDimSurface.setSize(dw, dh);
11034 mDimSurface.show();
11035 } catch (RuntimeException e) {
11036 Slog.w(TAG, "Failure showing dim surface", e);
11037 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011038 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11039 mLastDimWidth = dw;
11040 mLastDimHeight = dh;
11041 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011042 }
11043 }
11044
11045 /**
11046 * Set's the dim surface's layer and update dim parameters that will be used in
11047 * {@link updateSurface} after all windows are examined.
11048 */
11049 void updateParameters(WindowState w, long currentTime) {
11050 mDimSurface.setLayer(w.mAnimLayer-1);
11051
11052 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011053 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011054 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011055 if (mDimTargetAlpha != target) {
11056 // If the desired dim level has changed, then
11057 // start an animation to it.
11058 mLastDimAnimTime = currentTime;
11059 long duration = (w.mAnimating && w.mAnimation != null)
11060 ? w.mAnimation.computeDurationHint()
11061 : DEFAULT_DIM_DURATION;
11062 if (target > mDimTargetAlpha) {
11063 // This is happening behind the activity UI,
11064 // so we can make it run a little longer to
11065 // give a stronger impression without disrupting
11066 // the user.
11067 duration *= DIM_DURATION_MULTIPLIER;
11068 }
11069 if (duration < 1) {
11070 // Don't divide by zero
11071 duration = 1;
11072 }
11073 mDimTargetAlpha = target;
11074 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11075 }
11076 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011077
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011078 /**
11079 * Updating the surface's alpha. Returns true if the animation continues, or returns
11080 * false when the animation is finished and the dim surface is hidden.
11081 */
11082 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11083 if (!dimming) {
11084 if (mDimTargetAlpha != 0) {
11085 mLastDimAnimTime = currentTime;
11086 mDimTargetAlpha = 0;
11087 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11088 }
11089 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011090
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011091 boolean animating = false;
11092 if (mLastDimAnimTime != 0) {
11093 mDimCurrentAlpha += mDimDeltaPerMs
11094 * (currentTime-mLastDimAnimTime);
11095 boolean more = true;
11096 if (displayFrozen) {
11097 // If the display is frozen, there is no reason to animate.
11098 more = false;
11099 } else if (mDimDeltaPerMs > 0) {
11100 if (mDimCurrentAlpha > mDimTargetAlpha) {
11101 more = false;
11102 }
11103 } else if (mDimDeltaPerMs < 0) {
11104 if (mDimCurrentAlpha < mDimTargetAlpha) {
11105 more = false;
11106 }
11107 } else {
11108 more = false;
11109 }
11110
11111 // Do we need to continue animating?
11112 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011113 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011114 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11115 mLastDimAnimTime = currentTime;
11116 mDimSurface.setAlpha(mDimCurrentAlpha);
11117 animating = true;
11118 } else {
11119 mDimCurrentAlpha = mDimTargetAlpha;
11120 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011121 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011122 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11123 mDimSurface.setAlpha(mDimCurrentAlpha);
11124 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011125 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011126 + ": HIDE");
11127 try {
11128 mDimSurface.hide();
11129 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011130 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011131 }
11132 mDimShown = false;
11133 }
11134 }
11135 }
11136 return animating;
11137 }
11138
11139 public void printTo(PrintWriter pw) {
11140 pw.print(" mDimShown="); pw.print(mDimShown);
11141 pw.print(" current="); pw.print(mDimCurrentAlpha);
11142 pw.print(" target="); pw.print(mDimTargetAlpha);
11143 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11144 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11145 }
11146 }
11147
11148 /**
11149 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11150 * This is used for opening/closing transition for apps in compatible mode.
11151 */
11152 private static class FadeInOutAnimation extends Animation {
11153 int mWidth;
11154 boolean mFadeIn;
11155
11156 public FadeInOutAnimation(boolean fadeIn) {
11157 setInterpolator(new AccelerateInterpolator());
11158 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11159 mFadeIn = fadeIn;
11160 }
11161
11162 @Override
11163 protected void applyTransformation(float interpolatedTime, Transformation t) {
11164 float x = interpolatedTime;
11165 if (!mFadeIn) {
11166 x = 1.0f - x; // reverse the interpolation for fade out
11167 }
11168 if (x < 0.5) {
11169 // move the window out of the screen.
11170 t.getMatrix().setTranslate(mWidth, 0);
11171 } else {
11172 t.getMatrix().setTranslate(0, 0);// show
11173 t.setAlpha((x - 0.5f) * 2);
11174 }
11175 }
11176
11177 @Override
11178 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11179 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11180 mWidth = width;
11181 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011182
11183 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011184 public int getZAdjustment() {
11185 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011186 }
11187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011188}