blob: 7a9a6a217724ef70f17c70894f367525e9f3a9e6 [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 */
560 void broadcastDragStartedLw() {
561 // Cache a base-class instance of the clip metadata so that parceling
562 // works correctly in calling out to the apps.
563 mDataDescription = new ClipDescription(mData);
564 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700565 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700566
567 if (DEBUG_DRAG) {
568 Slog.d(TAG, "broadcasting DRAG_STARTED of " + mDataDescription);
569 }
570
571 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
572 mDataDescription, null);
Christopher Tate2c095f32010-10-04 14:13:40 -0700573 final int N = mWindows.size();
574 for (int i = 0; i < N; i++) {
575 // sendDragStartedLw() clones evt for local-process dispatch
576 sendDragStartedLw(mWindows.get(i), evt);
Christopher Tatea53146c2010-09-07 11:57:52 -0700577 }
578 evt.recycle();
579 }
580
581 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
582 * designated window is potentially a drop recipient. There are race situations
583 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
584 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700585 *
586 * This method clones the 'event' parameter if it's being delivered to the same
587 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700588 */
Christopher Tate2c095f32010-10-04 14:13:40 -0700589 private void sendDragStartedLw(WindowState newWin, DragEvent event) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700590 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700591 try {
Christopher Tate2c095f32010-10-04 14:13:40 -0700592 // clone for local callees since dispatch will recycle the event
593 if (Process.myPid() == newWin.mSession.mPid) {
594 event = DragEvent.obtain(event);
595 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700596 newWin.mClient.dispatchDragEvent(event);
597 // track each window that we've notified that the drag is starting
598 mNotifiedWindows.add(newWin);
599 } catch (RemoteException e) {
600 Slog.w(TAG, "Unable to drag-start window " + newWin);
601 }
602 }
603 }
604
605 /* helper - construct and send a DRAG_STARTED event only if the window has not
606 * previously been notified, i.e. it became visible after the drag operation
607 * was begun. This is a rare case.
608 */
609 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700610 if (mDragInProgress) {
611 // If we have sent the drag-started, we needn't do so again
612 for (WindowState ws : mNotifiedWindows) {
613 if (ws == newWin) {
614 return;
615 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700616 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700617 if (DEBUG_DRAG) {
618 Slog.d(TAG, "sending DRAG_STARTED to new window " + newWin);
619 }
620 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
621 mDataDescription, null);
622 // sendDragStartedLw() clones 'event' if the window is process-local
623 sendDragStartedLw(newWin, event);
624 event.recycle();
Christopher Tatea53146c2010-09-07 11:57:52 -0700625 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700626 }
627
628 void broadcastDragEnded() {
629 if (DEBUG_DRAG) {
630 Slog.d(TAG, "broadcasting DRAG_ENDED");
631 }
632 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, 0, 0, null, null);
633 synchronized (mWindowMap) {
634 for (WindowState ws: mNotifiedWindows) {
635 try {
636 ws.mClient.dispatchDragEvent(evt);
637 } catch (RemoteException e) {
638 Slog.w(TAG, "Unable to drag-end window " + ws);
639 }
640 }
641 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700642 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700643 }
644 evt.recycle();
645 }
646
647 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700648 final int myPid = Process.myPid();
649
650 // Move the surface to the given touch
651 mSurface.openTransaction();
652 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
653 mSurface.closeTransaction();
654
655 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700656 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
657 try {
658 // have we dragged over a new window?
659 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
660 if (DEBUG_DRAG) {
661 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
662 }
663 // force DRAG_EXITED_EVENT if appropriate
664 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
665 0, 0, null, null);
666 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700667 if (myPid != mTargetWindow.mSession.mPid) {
668 evt.recycle();
669 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700670 }
671 if (touchedWin != null) {
672 if (DEBUG_DRAG) {
673 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
674 }
675 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
676 x, y, null, null);
677 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700678 if (myPid != touchedWin.mSession.mPid) {
679 evt.recycle();
680 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700681 }
682 } catch (RemoteException e) {
683 Slog.w(TAG, "can't send drag notification to windows");
684 }
685 mTargetWindow = touchedWin;
686 }
687
688 // Tell the drop target about the data, and then broadcast the drag-ended notification
689 void notifyDropLw(float x, float y) {
690 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
691 if (touchedWin != null) {
692 if (DEBUG_DRAG) {
693 Slog.d(TAG, "sending DROP to " + touchedWin);
694 }
Christopher Tate2c095f32010-10-04 14:13:40 -0700695 final int myPid = Process.myPid();
Christopher Tatea53146c2010-09-07 11:57:52 -0700696 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x, y, null, mData);
697 try {
698 touchedWin.mClient.dispatchDragEvent(evt);
699 } catch (RemoteException e) {
700 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
701 }
Christopher Tate2c095f32010-10-04 14:13:40 -0700702 if (myPid != touchedWin.mSession.mPid) {
703 evt.recycle();
704 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700705 }
706 }
707
708 // Find the visible, touch-deliverable window under the given point
709 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
710 WindowState touchedWin = null;
711 final int x = (int) xf;
712 final int y = (int) yf;
713 final ArrayList<WindowState> windows = mWindows;
714 final int N = windows.size();
715 for (int i = N - 1; i >= 0; i--) {
716 WindowState child = windows.get(i);
717 final int flags = child.mAttrs.flags;
718 if (!child.isVisibleLw()) {
719 // not visible == don't tell about drags
720 continue;
721 }
722 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
723 // not touchable == don't tell about drags
724 continue;
725 }
726 // account for the window's decor etc
727 tmpRect.set(child.mFrame);
728 if (child.mTouchableInsets == ViewTreeObserver
729 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
730 // The point is inside of the window if it is
731 // inside the frame, AND the content part of that
732 // frame that was given by the application.
733 tmpRect.left += child.mGivenContentInsets.left;
734 tmpRect.top += child.mGivenContentInsets.top;
735 tmpRect.right -= child.mGivenContentInsets.right;
736 tmpRect.bottom -= child.mGivenContentInsets.bottom;
737 } else if (child.mTouchableInsets == ViewTreeObserver
738 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
739 // The point is inside of the window if it is
740 // inside the frame, AND the visible part of that
741 // frame that was given by the application.
742 tmpRect.left += child.mGivenVisibleInsets.left;
743 tmpRect.top += child.mGivenVisibleInsets.top;
744 tmpRect.right -= child.mGivenVisibleInsets.right;
745 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
746 }
747 final int touchFlags = flags &
748 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
749 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
750 if (tmpRect.contains(x, y) || touchFlags == 0) {
751 // Found it
752 touchedWin = child;
753 break;
754 }
755 }
756
757 return touchedWin;
758 }
759 }
760
761 DragState mDragState = null;
762 private final InputHandler mDragInputHandler = new BaseInputHandler() {
763 @Override
764 public void handleMotion(MotionEvent event, Runnable finishedCallback) {
765 boolean endDrag = false;
766 final float newX = event.getRawX();
767 final float newY = event.getRawY();
768
769 try {
770 if (mDragState != null) {
771 switch (event.getAction()) {
772 case MotionEvent.ACTION_DOWN: {
773 if (DEBUG_DRAG) {
774 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
775 }
776 } break;
777
778 case MotionEvent.ACTION_MOVE: {
779 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700780 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700781 mDragState.notifyMoveLw(newX, newY);
782 }
783 } break;
784
785 case MotionEvent.ACTION_UP: {
786 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
787 + newX + "," + newY);
788 synchronized (mWindowMap) {
789 mDragState.notifyDropLw(newX, newY);
790 }
791 endDrag = true;
792 } break;
793
794 case MotionEvent.ACTION_CANCEL: {
795 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
796 endDrag = true;
797 } break;
798 }
799
800 if (endDrag) {
801 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
802 // tell all the windows that the drag has ended
803 mDragState.broadcastDragEnded();
804
805 // stop intercepting input
806 mDragState.unregister();
807 mInputMonitor.updateInputWindowsLw();
808
809 // free our resources and drop all the object references
810 mDragState.reset();
811 mDragState = null;
812 }
813 }
814 } catch (Exception e) {
815 Slog.e(TAG, "Exception caught by drag handleMotion", e);
816 } finally {
817 finishedCallback.run();
818 }
819 }
820 };
821
822 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 * Whether the UI is currently running in touch mode (not showing
824 * navigational focus because the user is directly pressing the screen).
825 */
826 boolean mInTouchMode = false;
827
828 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700829 private ArrayList<WindowChangeListener> mWindowChangeListeners =
830 new ArrayList<WindowChangeListener>();
831 private boolean mWindowsChanged = false;
832
833 public interface WindowChangeListener {
834 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700835 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837
Dianne Hackbornc485a602009-03-24 22:39:49 -0700838 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700839 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700840
841 // The frame use to limit the size of the app running in compatibility mode.
842 Rect mCompatibleScreenFrame = new Rect();
843 // The surface used to fill the outer rim of the app running in compatibility mode.
844 Surface mBackgroundFillerSurface = null;
845 boolean mBackgroundFillerShown = false;
846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 public static WindowManagerService main(Context context,
848 PowerManagerService pm, boolean haveInputMethods) {
849 WMThread thr = new WMThread(context, pm, haveInputMethods);
850 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 synchronized (thr) {
853 while (thr.mService == null) {
854 try {
855 thr.wait();
856 } catch (InterruptedException e) {
857 }
858 }
859 }
Romain Guy06882f82009-06-10 13:36:04 -0700860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 return thr.mService;
862 }
Romain Guy06882f82009-06-10 13:36:04 -0700863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 static class WMThread extends Thread {
865 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 private final Context mContext;
868 private final PowerManagerService mPM;
869 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 public WMThread(Context context, PowerManagerService pm,
872 boolean haveInputMethods) {
873 super("WindowManager");
874 mContext = context;
875 mPM = pm;
876 mHaveInputMethods = haveInputMethods;
877 }
Romain Guy06882f82009-06-10 13:36:04 -0700878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 public void run() {
880 Looper.prepare();
881 WindowManagerService s = new WindowManagerService(mContext, mPM,
882 mHaveInputMethods);
883 android.os.Process.setThreadPriority(
884 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700885 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 synchronized (this) {
888 mService = s;
889 notifyAll();
890 }
Romain Guy06882f82009-06-10 13:36:04 -0700891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 Looper.loop();
893 }
894 }
895
896 static class PolicyThread extends Thread {
897 private final WindowManagerPolicy mPolicy;
898 private final WindowManagerService mService;
899 private final Context mContext;
900 private final PowerManagerService mPM;
901 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 public PolicyThread(WindowManagerPolicy policy,
904 WindowManagerService service, Context context,
905 PowerManagerService pm) {
906 super("WindowManagerPolicy");
907 mPolicy = policy;
908 mService = service;
909 mContext = context;
910 mPM = pm;
911 }
Romain Guy06882f82009-06-10 13:36:04 -0700912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800913 public void run() {
914 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800915 WindowManagerPolicyThread.set(this, Looper.myLooper());
916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800918 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 android.os.Process.setThreadPriority(
920 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700921 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 synchronized (this) {
925 mRunning = true;
926 notifyAll();
927 }
Romain Guy06882f82009-06-10 13:36:04 -0700928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 Looper.loop();
930 }
931 }
932
933 private WindowManagerService(Context context, PowerManagerService pm,
934 boolean haveInputMethods) {
935 mContext = context;
936 mHaveInputMethods = haveInputMethods;
937 mLimitedAlphaCompositing = context.getResources().getBoolean(
938 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 mPowerManager = pm;
941 mPowerManager.setPolicy(mPolicy);
942 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
943 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
944 "SCREEN_FROZEN");
945 mScreenFrozenLock.setReferenceCounted(false);
946
947 mActivityManager = ActivityManagerNative.getDefault();
948 mBatteryStats = BatteryStatsService.getService();
949
950 // Get persisted window scale setting
951 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
952 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
953 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
954 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700955
Jim Miller284b62e2010-06-08 14:27:42 -0700956 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
957 IntentFilter filter = new IntentFilter();
958 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
959 mContext.registerReceiver(mBroadcastReceiver, filter);
960
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700961 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
962 "KEEP_SCREEN_ON_FLAG");
963 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964
Jeff Browne33348b2010-07-15 23:54:05 -0700965 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
968 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 synchronized (thr) {
971 while (!thr.mRunning) {
972 try {
973 thr.wait();
974 } catch (InterruptedException e) {
975 }
976 }
977 }
Romain Guy06882f82009-06-10 13:36:04 -0700978
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700979 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 // Add ourself to the Watchdog monitors.
982 Watchdog.getInstance().addMonitor(this);
983 }
984
985 @Override
986 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
987 throws RemoteException {
988 try {
989 return super.onTransact(code, data, reply, flags);
990 } catch (RuntimeException e) {
991 // The window manager only throws security exceptions, so let's
992 // log all others.
993 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800994 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 }
996 throw e;
997 }
998 }
999
Jeff Browne33348b2010-07-15 23:54:05 -07001000 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001002 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 TAG, "Adding window " + window + " at "
1004 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1005 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001006 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 }
1008
Jeff Browne33348b2010-07-15 23:54:05 -07001009 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001011 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 TAG, "Adding window " + window + " at "
1013 + i + " of " + mWindows.size() + " (before " + pos + ")");
1014 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001015 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 }
1017
1018 //This method finds out the index of a window that has the same app token as
1019 //win. used for z ordering the windows in mWindows
1020 private int findIdxBasedOnAppTokens(WindowState win) {
1021 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001022 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 int jmax = localmWindows.size();
1024 if(jmax == 0) {
1025 return -1;
1026 }
1027 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001028 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 if(wentry.mAppToken == win.mAppToken) {
1030 return j;
1031 }
1032 }
1033 return -1;
1034 }
Romain Guy06882f82009-06-10 13:36:04 -07001035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1037 final IWindow client = win.mClient;
1038 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001039 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 final int N = localmWindows.size();
1042 final WindowState attached = win.mAttachedWindow;
1043 int i;
1044 if (attached == null) {
1045 int tokenWindowsPos = token.windows.size();
1046 if (token.appWindowToken != null) {
1047 int index = tokenWindowsPos-1;
1048 if (index >= 0) {
1049 // If this application has existing windows, we
1050 // simply place the new window on top of them... but
1051 // keep the starting window on top.
1052 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1053 // Base windows go behind everything else.
1054 placeWindowBefore(token.windows.get(0), win);
1055 tokenWindowsPos = 0;
1056 } else {
1057 AppWindowToken atoken = win.mAppToken;
1058 if (atoken != null &&
1059 token.windows.get(index) == atoken.startingWindow) {
1060 placeWindowBefore(token.windows.get(index), win);
1061 tokenWindowsPos--;
1062 } else {
1063 int newIdx = findIdxBasedOnAppTokens(win);
1064 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001065 //there is a window above this one associated with the same
1066 //apptoken note that the window could be a floating window
1067 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001069 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001070 TAG, "Adding window " + win + " at "
1071 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001073 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 }
1076 }
1077 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001078 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 TAG, "Figuring out where to add app window "
1080 + client.asBinder() + " (token=" + token + ")");
1081 // Figure out where the window should go, based on the
1082 // order of applications.
1083 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001084 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 for (i=NA-1; i>=0; i--) {
1086 AppWindowToken t = mAppTokens.get(i);
1087 if (t == token) {
1088 i--;
1089 break;
1090 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001091
Dianne Hackborna8f60182009-09-01 19:01:50 -07001092 // We haven't reached the token yet; if this token
1093 // is not going to the bottom and has windows, we can
1094 // use it as an anchor for when we do reach the token.
1095 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 pos = t.windows.get(0);
1097 }
1098 }
1099 // We now know the index into the apps. If we found
1100 // an app window above, that gives us the position; else
1101 // we need to look some more.
1102 if (pos != null) {
1103 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001104 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 if (atoken != null) {
1106 final int NC = atoken.windows.size();
1107 if (NC > 0) {
1108 WindowState bottom = atoken.windows.get(0);
1109 if (bottom.mSubLayer < 0) {
1110 pos = bottom;
1111 }
1112 }
1113 }
1114 placeWindowBefore(pos, win);
1115 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001116 // Continue looking down until we find the first
1117 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 while (i >= 0) {
1119 AppWindowToken t = mAppTokens.get(i);
1120 final int NW = t.windows.size();
1121 if (NW > 0) {
1122 pos = t.windows.get(NW-1);
1123 break;
1124 }
1125 i--;
1126 }
1127 if (pos != null) {
1128 // Move in front of any windows attached to this
1129 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001130 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 if (atoken != null) {
1132 final int NC = atoken.windows.size();
1133 if (NC > 0) {
1134 WindowState top = atoken.windows.get(NC-1);
1135 if (top.mSubLayer >= 0) {
1136 pos = top;
1137 }
1138 }
1139 }
1140 placeWindowAfter(pos, win);
1141 } else {
1142 // Just search for the start of this layer.
1143 final int myLayer = win.mBaseLayer;
1144 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001145 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 if (w.mBaseLayer > myLayer) {
1147 break;
1148 }
1149 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001150 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001151 TAG, "Adding window " + win + " at "
1152 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001154 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 }
1156 }
1157 }
1158 } else {
1159 // Figure out where window should go, based on layer.
1160 final int myLayer = win.mBaseLayer;
1161 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001162 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 i++;
1164 break;
1165 }
1166 }
1167 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001168 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001169 TAG, "Adding window " + win + " at "
1170 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001172 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 }
1174 if (addToToken) {
1175 token.windows.add(tokenWindowsPos, win);
1176 }
1177
1178 } else {
1179 // Figure out this window's ordering relative to the window
1180 // it is attached to.
1181 final int NA = token.windows.size();
1182 final int sublayer = win.mSubLayer;
1183 int largestSublayer = Integer.MIN_VALUE;
1184 WindowState windowWithLargestSublayer = null;
1185 for (i=0; i<NA; i++) {
1186 WindowState w = token.windows.get(i);
1187 final int wSublayer = w.mSubLayer;
1188 if (wSublayer >= largestSublayer) {
1189 largestSublayer = wSublayer;
1190 windowWithLargestSublayer = w;
1191 }
1192 if (sublayer < 0) {
1193 // For negative sublayers, we go below all windows
1194 // in the same sublayer.
1195 if (wSublayer >= sublayer) {
1196 if (addToToken) {
1197 token.windows.add(i, win);
1198 }
1199 placeWindowBefore(
1200 wSublayer >= 0 ? attached : w, win);
1201 break;
1202 }
1203 } else {
1204 // For positive sublayers, we go above all windows
1205 // in the same sublayer.
1206 if (wSublayer > sublayer) {
1207 if (addToToken) {
1208 token.windows.add(i, win);
1209 }
1210 placeWindowBefore(w, win);
1211 break;
1212 }
1213 }
1214 }
1215 if (i >= NA) {
1216 if (addToToken) {
1217 token.windows.add(win);
1218 }
1219 if (sublayer < 0) {
1220 placeWindowBefore(attached, win);
1221 } else {
1222 placeWindowAfter(largestSublayer >= 0
1223 ? windowWithLargestSublayer
1224 : attached,
1225 win);
1226 }
1227 }
1228 }
Romain Guy06882f82009-06-10 13:36:04 -07001229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 if (win.mAppToken != null && addToToken) {
1231 win.mAppToken.allAppWindows.add(win);
1232 }
1233 }
Romain Guy06882f82009-06-10 13:36:04 -07001234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 static boolean canBeImeTarget(WindowState w) {
1236 final int fl = w.mAttrs.flags
1237 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1238 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1239 return w.isVisibleOrAdding();
1240 }
1241 return false;
1242 }
Romain Guy06882f82009-06-10 13:36:04 -07001243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001244 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001245 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 final int N = localmWindows.size();
1247 WindowState w = null;
1248 int i = N;
1249 while (i > 0) {
1250 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001251 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001252
Joe Onorato8a9b2202010-02-26 18:56:32 -08001253 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 // + Integer.toHexString(w.mAttrs.flags));
1255 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001256 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 // Yet more tricksyness! If this window is a "starting"
1259 // window, we do actually want to be on top of it, but
1260 // it is not -really- where input will go. So if the caller
1261 // is not actually looking to move the IME, look down below
1262 // for a real window to target...
1263 if (!willMove
1264 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1265 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001266 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1268 i--;
1269 w = wb;
1270 }
1271 }
1272 break;
1273 }
1274 }
Romain Guy06882f82009-06-10 13:36:04 -07001275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -07001277
Joe Onorato8a9b2202010-02-26 18:56:32 -08001278 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 if (willMove && w != null) {
1282 final WindowState curTarget = mInputMethodTarget;
1283 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 // Now some fun for dealing with window animations that
1286 // modify the Z order. We need to look at all windows below
1287 // the current target that are in this app, finding the highest
1288 // visible one in layering.
1289 AppWindowToken token = curTarget.mAppToken;
1290 WindowState highestTarget = null;
1291 int highestPos = 0;
1292 if (token.animating || token.animation != null) {
1293 int pos = 0;
1294 pos = localmWindows.indexOf(curTarget);
1295 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001296 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 if (win.mAppToken != token) {
1298 break;
1299 }
1300 if (!win.mRemoved) {
1301 if (highestTarget == null || win.mAnimLayer >
1302 highestTarget.mAnimLayer) {
1303 highestTarget = win;
1304 highestPos = pos;
1305 }
1306 }
1307 pos--;
1308 }
1309 }
Romain Guy06882f82009-06-10 13:36:04 -07001310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001312 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 + mNextAppTransition + " " + highestTarget
1314 + " animating=" + highestTarget.isAnimating()
1315 + " layer=" + highestTarget.mAnimLayer
1316 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001317
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001318 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 // If we are currently setting up for an animation,
1320 // hold everything until we can find out what will happen.
1321 mInputMethodTargetWaitingAnim = true;
1322 mInputMethodTarget = highestTarget;
1323 return highestPos + 1;
1324 } else if (highestTarget.isAnimating() &&
1325 highestTarget.mAnimLayer > w.mAnimLayer) {
1326 // If the window we are currently targeting is involved
1327 // with an animation, and it is on top of the next target
1328 // we will be over, then hold off on moving until
1329 // that is done.
1330 mInputMethodTarget = highestTarget;
1331 return highestPos + 1;
1332 }
1333 }
1334 }
1335 }
Romain Guy06882f82009-06-10 13:36:04 -07001336
Joe Onorato8a9b2202010-02-26 18:56:32 -08001337 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 if (w != null) {
1339 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001340 if (DEBUG_INPUT_METHOD) {
1341 RuntimeException e = null;
1342 if (!HIDE_STACK_CRAWLS) {
1343 e = new RuntimeException();
1344 e.fillInStackTrace();
1345 }
1346 Slog.w(TAG, "Moving IM target from "
1347 + mInputMethodTarget + " to " + w, e);
1348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 mInputMethodTarget = w;
1350 if (w.mAppToken != null) {
1351 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1352 } else {
1353 setInputMethodAnimLayerAdjustment(0);
1354 }
1355 }
1356 return i+1;
1357 }
1358 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001359 if (DEBUG_INPUT_METHOD) {
1360 RuntimeException e = null;
1361 if (!HIDE_STACK_CRAWLS) {
1362 e = new RuntimeException();
1363 e.fillInStackTrace();
1364 }
1365 Slog.w(TAG, "Moving IM target from "
1366 + mInputMethodTarget + " to null", e);
1367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 mInputMethodTarget = null;
1369 setInputMethodAnimLayerAdjustment(0);
1370 }
1371 return -1;
1372 }
Romain Guy06882f82009-06-10 13:36:04 -07001373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 void addInputMethodWindowToListLocked(WindowState win) {
1375 int pos = findDesiredInputMethodWindowIndexLocked(true);
1376 if (pos >= 0) {
1377 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001378 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001379 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001381 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 moveInputMethodDialogsLocked(pos+1);
1383 return;
1384 }
1385 win.mTargetAppToken = null;
1386 addWindowToListInOrderLocked(win, true);
1387 moveInputMethodDialogsLocked(pos);
1388 }
Romain Guy06882f82009-06-10 13:36:04 -07001389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 mInputMethodAnimLayerAdjustment = adj;
1393 WindowState imw = mInputMethodWindow;
1394 if (imw != null) {
1395 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001396 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 + " anim layer: " + imw.mAnimLayer);
1398 int wi = imw.mChildWindows.size();
1399 while (wi > 0) {
1400 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001401 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001403 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 + " anim layer: " + cw.mAnimLayer);
1405 }
1406 }
1407 int di = mInputMethodDialogs.size();
1408 while (di > 0) {
1409 di --;
1410 imw = mInputMethodDialogs.get(di);
1411 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001412 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 + " anim layer: " + imw.mAnimLayer);
1414 }
1415 }
Romain Guy06882f82009-06-10 13:36:04 -07001416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1418 int wpos = mWindows.indexOf(win);
1419 if (wpos >= 0) {
1420 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001421 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001423 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 int NC = win.mChildWindows.size();
1425 while (NC > 0) {
1426 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001427 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 int cpos = mWindows.indexOf(cw);
1429 if (cpos >= 0) {
1430 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001431 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001432 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 mWindows.remove(cpos);
1434 }
1435 }
1436 }
1437 return interestingPos;
1438 }
Romain Guy06882f82009-06-10 13:36:04 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 private void reAddWindowToListInOrderLocked(WindowState win) {
1441 addWindowToListInOrderLocked(win, false);
1442 // This is a hack to get all of the child windows added as well
1443 // at the right position. Child windows should be rare and
1444 // this case should be rare, so it shouldn't be that big a deal.
1445 int wpos = mWindows.indexOf(win);
1446 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001447 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001448 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001450 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 reAddWindowLocked(wpos, win);
1452 }
1453 }
Romain Guy06882f82009-06-10 13:36:04 -07001454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 void logWindowList(String prefix) {
1456 int N = mWindows.size();
1457 while (N > 0) {
1458 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001459 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 }
1461 }
Romain Guy06882f82009-06-10 13:36:04 -07001462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 void moveInputMethodDialogsLocked(int pos) {
1464 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001467 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 for (int i=0; i<N; i++) {
1469 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1470 }
1471 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001472 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 logWindowList(" ");
1474 }
Romain Guy06882f82009-06-10 13:36:04 -07001475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 if (pos >= 0) {
1477 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1478 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001479 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if (wp == mInputMethodWindow) {
1481 pos++;
1482 }
1483 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 for (int i=0; i<N; i++) {
1486 WindowState win = dialogs.get(i);
1487 win.mTargetAppToken = targetAppToken;
1488 pos = reAddWindowLocked(pos, win);
1489 }
1490 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001491 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 logWindowList(" ");
1493 }
1494 return;
1495 }
1496 for (int i=0; i<N; i++) {
1497 WindowState win = dialogs.get(i);
1498 win.mTargetAppToken = null;
1499 reAddWindowToListInOrderLocked(win);
1500 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001501 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 logWindowList(" ");
1503 }
1504 }
1505 }
Romain Guy06882f82009-06-10 13:36:04 -07001506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1508 final WindowState imWin = mInputMethodWindow;
1509 final int DN = mInputMethodDialogs.size();
1510 if (imWin == null && DN == 0) {
1511 return false;
1512 }
Romain Guy06882f82009-06-10 13:36:04 -07001513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1515 if (imPos >= 0) {
1516 // In this case, the input method windows are to be placed
1517 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 // First check to see if the input method windows are already
1520 // located here, and contiguous.
1521 final int N = mWindows.size();
1522 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001523 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 // Figure out the actual input method window that should be
1526 // at the bottom of their stack.
1527 WindowState baseImWin = imWin != null
1528 ? imWin : mInputMethodDialogs.get(0);
1529 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001530 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 if (cw.mSubLayer < 0) baseImWin = cw;
1532 }
Romain Guy06882f82009-06-10 13:36:04 -07001533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (firstImWin == baseImWin) {
1535 // The windows haven't moved... but are they still contiguous?
1536 // First find the top IM window.
1537 int pos = imPos+1;
1538 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001539 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 break;
1541 }
1542 pos++;
1543 }
1544 pos++;
1545 // Now there should be no more input method windows above.
1546 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001547 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 break;
1549 }
1550 pos++;
1551 }
1552 if (pos >= N) {
1553 // All is good!
1554 return false;
1555 }
1556 }
Romain Guy06882f82009-06-10 13:36:04 -07001557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 if (imWin != null) {
1559 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001560 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 logWindowList(" ");
1562 }
1563 imPos = tmpRemoveWindowLocked(imPos, imWin);
1564 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001565 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 logWindowList(" ");
1567 }
1568 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1569 reAddWindowLocked(imPos, imWin);
1570 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001571 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 logWindowList(" ");
1573 }
1574 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1575 } else {
1576 moveInputMethodDialogsLocked(imPos);
1577 }
Romain Guy06882f82009-06-10 13:36:04 -07001578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 } else {
1580 // In this case, the input method windows go in a fixed layer,
1581 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001584 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 tmpRemoveWindowLocked(0, imWin);
1586 imWin.mTargetAppToken = null;
1587 reAddWindowToListInOrderLocked(imWin);
1588 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001589 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590 logWindowList(" ");
1591 }
1592 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1593 } else {
1594 moveInputMethodDialogsLocked(-1);;
1595 }
Romain Guy06882f82009-06-10 13:36:04 -07001596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 }
Romain Guy06882f82009-06-10 13:36:04 -07001598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 if (needAssignLayers) {
1600 assignLayersLocked();
1601 }
Romain Guy06882f82009-06-10 13:36:04 -07001602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 return true;
1604 }
Romain Guy06882f82009-06-10 13:36:04 -07001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 void adjustInputMethodDialogsLocked() {
1607 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1608 }
Romain Guy06882f82009-06-10 13:36:04 -07001609
Dianne Hackborn25994b42009-09-04 14:21:19 -07001610 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001611 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001612 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1613 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1614 ? wallpaperTarget.mAppToken.animation : null)
1615 + " upper=" + mUpperWallpaperTarget
1616 + " lower=" + mLowerWallpaperTarget);
1617 return (wallpaperTarget != null
1618 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1619 && wallpaperTarget.mAppToken.animation != null)))
1620 || mUpperWallpaperTarget != null
1621 || mLowerWallpaperTarget != null;
1622 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001623
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001624 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1625 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001626
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001627 int adjustWallpaperWindowsLocked() {
1628 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001629
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001630 final int dw = mDisplay.getWidth();
1631 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001632
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001633 // First find top-most window that has asked to be on top of the
1634 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001635 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001636 int N = localmWindows.size();
1637 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001638 WindowState foundW = null;
1639 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001640 WindowState topCurW = null;
1641 int topCurI = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001642 int i = N;
1643 while (i > 0) {
1644 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001645 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001646 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1647 if (topCurW == null) {
1648 topCurW = w;
1649 topCurI = i;
1650 }
1651 continue;
1652 }
1653 topCurW = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001654 if (w.mAppToken != null) {
1655 // If this window's app token is hidden and not animating,
1656 // it is of no interest to us.
1657 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001658 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001659 "Skipping hidden or animating token: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001660 topCurW = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001661 continue;
1662 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001663 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001664 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001665 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1666 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001667 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001668 && (mWallpaperTarget == w
1669 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001670 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001671 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001672 foundW = w;
1673 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001674 if (w == mWallpaperTarget && ((w.mAppToken != null
1675 && w.mAppToken.animation != null)
1676 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001677 // The current wallpaper target is animating, so we'll
1678 // look behind it for another possible target and figure
1679 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001680 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001681 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001682 continue;
1683 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001684 break;
1685 }
1686 }
1687
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001688 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001689 // If we are currently waiting for an app transition, and either
1690 // the current target or the next target are involved with it,
1691 // then hold off on doing anything with the wallpaper.
1692 // Note that we are checking here for just whether the target
1693 // is part of an app token... which is potentially overly aggressive
1694 // (the app token may not be involved in the transition), but good
1695 // enough (we'll just wait until whatever transition is pending
1696 // executes).
1697 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001698 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001699 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001700 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001701 }
1702 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001703 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001704 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001705 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001706 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001707 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001708
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001709 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001710 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001712 + " oldTarget: " + mWallpaperTarget);
1713 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001714
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001715 mLowerWallpaperTarget = null;
1716 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001717
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001718 WindowState oldW = mWallpaperTarget;
1719 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001720
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001721 // Now what is happening... if the current and new targets are
1722 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001723 if (foundW != null && oldW != null) {
1724 boolean oldAnim = oldW.mAnimation != null
1725 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1726 boolean foundAnim = foundW.mAnimation != null
1727 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001728 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001729 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001730 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001731 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001732 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001733 int oldI = localmWindows.indexOf(oldW);
1734 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001735 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001736 }
1737 if (oldI >= 0) {
1738 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001739 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001740 + "=" + oldW + "; new#" + foundI
1741 + "=" + foundW);
1742 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001743
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001744 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001745 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001746 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001747 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001748 }
1749 mWallpaperTarget = oldW;
1750 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001751
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001752 // Now set the upper and lower wallpaper targets
1753 // correctly, and make sure that we are positioning
1754 // the wallpaper below the lower.
1755 if (foundI > oldI) {
1756 // The new target is on top of the old one.
1757 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001758 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001759 }
1760 mUpperWallpaperTarget = foundW;
1761 mLowerWallpaperTarget = oldW;
1762 foundW = oldW;
1763 foundI = oldI;
1764 } else {
1765 // The new target is below the old one.
1766 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001767 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001768 }
1769 mUpperWallpaperTarget = oldW;
1770 mLowerWallpaperTarget = foundW;
1771 }
1772 }
1773 }
1774 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001775
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001776 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001777 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001778 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1779 || (mLowerWallpaperTarget.mAppToken != null
1780 && mLowerWallpaperTarget.mAppToken.animation != null);
1781 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1782 || (mUpperWallpaperTarget.mAppToken != null
1783 && mUpperWallpaperTarget.mAppToken.animation != null);
1784 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001785 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001786 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001787 }
1788 mLowerWallpaperTarget = null;
1789 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001790 }
1791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001792
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001793 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001794 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001795 // The window is visible to the compositor... but is it visible
1796 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001797 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001798 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001799
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001800 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001801 // its layer adjustment. Only do this if we are not transfering
1802 // between two wallpaper targets.
1803 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001804 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001805 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001806
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001807 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1808 * TYPE_LAYER_MULTIPLIER
1809 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001810
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001811 // Now w is the window we are supposed to be behind... but we
1812 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001813 // AND any starting window associated with it, AND below the
1814 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001815 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001816 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001817 if (wb.mBaseLayer < maxLayer &&
1818 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001819 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001820 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001821 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001822 // This window is not related to the previous one in any
1823 // interesting way, so stop here.
1824 break;
1825 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001826 foundW = wb;
1827 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001828 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001829 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001830 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001831 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001832
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001833 if (foundW == null && topCurW != null) {
1834 // There is no wallpaper target, so it goes at the bottom.
1835 // We will assume it is the same place as last time, if known.
1836 foundW = topCurW;
1837 foundI = topCurI+1;
1838 } else {
1839 // Okay i is the position immediately above the wallpaper. Look at
1840 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001841 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001842 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001843
Dianne Hackborn284ac932009-08-28 10:34:25 -07001844 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001845 if (mWallpaperTarget.mWallpaperX >= 0) {
1846 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001847 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001848 }
1849 if (mWallpaperTarget.mWallpaperY >= 0) {
1850 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001851 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001852 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001853 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001854
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001855 // Start stepping backwards from here, ensuring that our wallpaper windows
1856 // are correctly placed.
1857 int curTokenIndex = mWallpaperTokens.size();
1858 while (curTokenIndex > 0) {
1859 curTokenIndex--;
1860 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001861 if (token.hidden == visible) {
1862 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1863 token.hidden = !visible;
1864 // Need to do a layout to ensure the wallpaper now has the
1865 // correct size.
1866 mLayoutNeeded = true;
1867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001868
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001869 int curWallpaperIndex = token.windows.size();
1870 while (curWallpaperIndex > 0) {
1871 curWallpaperIndex--;
1872 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001873
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001874 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001875 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001876 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001877
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001878 // First, make sure the client has the current visibility
1879 // state.
1880 if (wallpaper.mWallpaperVisible != visible) {
1881 wallpaper.mWallpaperVisible = visible;
1882 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001883 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001884 "Setting visibility of wallpaper " + wallpaper
1885 + ": " + visible);
1886 wallpaper.mClient.dispatchAppVisibility(visible);
1887 } catch (RemoteException e) {
1888 }
1889 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001890
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001891 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001892 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001893 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001894
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001895 // First, if this window is at the current index, then all
1896 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001897 if (wallpaper == foundW) {
1898 foundI--;
1899 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001900 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001901 continue;
1902 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001903
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001904 // The window didn't match... the current wallpaper window,
1905 // wherever it is, is in the wrong place, so make sure it is
1906 // not in the list.
1907 int oldIndex = localmWindows.indexOf(wallpaper);
1908 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001909 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001910 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001911 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001912 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001913 if (oldIndex < foundI) {
1914 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001915 }
1916 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001917
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001918 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001919 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001920 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001921 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001922
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001923 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001924 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001925 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001926 }
1927 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001928
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001929 return changed;
1930 }
1931
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001932 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001933 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001934 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001935 mWallpaperAnimLayerAdjustment = adj;
1936 int curTokenIndex = mWallpaperTokens.size();
1937 while (curTokenIndex > 0) {
1938 curTokenIndex--;
1939 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1940 int curWallpaperIndex = token.windows.size();
1941 while (curWallpaperIndex > 0) {
1942 curWallpaperIndex--;
1943 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1944 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001945 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001946 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001947 }
1948 }
1949 }
1950
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001951 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1952 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001953 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001954 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001955 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001956 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001957 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1958 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1959 changed = wallpaperWin.mXOffset != offset;
1960 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001961 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001962 + wallpaperWin + " x: " + offset);
1963 wallpaperWin.mXOffset = offset;
1964 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001965 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001966 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001967 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001968 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001969 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001970
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001971 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001972 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001973 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1974 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1975 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001976 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001977 + wallpaperWin + " y: " + offset);
1978 changed = true;
1979 wallpaperWin.mYOffset = offset;
1980 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001981 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001982 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001983 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001984 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001985 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001986
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001987 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001988 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001989 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001990 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1991 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001992 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001993 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001994 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001995 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001996 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1997 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001998 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001999 if (mWaitingOnWallpaper != null) {
2000 long start = SystemClock.uptimeMillis();
2001 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2002 < start) {
2003 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002004 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002005 "Waiting for offset complete...");
2006 mWindowMap.wait(WALLPAPER_TIMEOUT);
2007 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002008 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002009 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002010 if ((start+WALLPAPER_TIMEOUT)
2011 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002013 + wallpaperWin);
2014 mLastWallpaperTimeoutTime = start;
2015 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002016 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002017 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002018 }
2019 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002020 } catch (RemoteException e) {
2021 }
2022 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002023
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002024 return changed;
2025 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002026
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002027 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002028 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002029 if (mWaitingOnWallpaper != null &&
2030 mWaitingOnWallpaper.mClient.asBinder() == window) {
2031 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002032 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002033 }
2034 }
2035 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002036
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002037 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002038 final int dw = mDisplay.getWidth();
2039 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002040
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002041 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002042
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002043 WindowState target = mWallpaperTarget;
2044 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002045 if (target.mWallpaperX >= 0) {
2046 mLastWallpaperX = target.mWallpaperX;
2047 } else if (changingTarget.mWallpaperX >= 0) {
2048 mLastWallpaperX = changingTarget.mWallpaperX;
2049 }
2050 if (target.mWallpaperY >= 0) {
2051 mLastWallpaperY = target.mWallpaperY;
2052 } else if (changingTarget.mWallpaperY >= 0) {
2053 mLastWallpaperY = changingTarget.mWallpaperY;
2054 }
2055 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002056
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002057 int curTokenIndex = mWallpaperTokens.size();
2058 while (curTokenIndex > 0) {
2059 curTokenIndex--;
2060 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2061 int curWallpaperIndex = token.windows.size();
2062 while (curWallpaperIndex > 0) {
2063 curWallpaperIndex--;
2064 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2065 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2066 wallpaper.computeShownFrameLocked();
2067 changed = true;
2068 // We only want to be synchronous with one wallpaper.
2069 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002070 }
2071 }
2072 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002073
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002074 return changed;
2075 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002076
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002077 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002078 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002079 final int dw = mDisplay.getWidth();
2080 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002081
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002082 int curTokenIndex = mWallpaperTokens.size();
2083 while (curTokenIndex > 0) {
2084 curTokenIndex--;
2085 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002086 if (token.hidden == visible) {
2087 token.hidden = !visible;
2088 // Need to do a layout to ensure the wallpaper now has the
2089 // correct size.
2090 mLayoutNeeded = true;
2091 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002092
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002093 int curWallpaperIndex = token.windows.size();
2094 while (curWallpaperIndex > 0) {
2095 curWallpaperIndex--;
2096 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2097 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002098 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002099 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002100
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002101 if (wallpaper.mWallpaperVisible != visible) {
2102 wallpaper.mWallpaperVisible = visible;
2103 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002104 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002105 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002106 + ": " + visible);
2107 wallpaper.mClient.dispatchAppVisibility(visible);
2108 } catch (RemoteException e) {
2109 }
2110 }
2111 }
2112 }
2113 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002115 public int addWindow(Session session, IWindow client,
2116 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002117 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 int res = mPolicy.checkAddPermission(attrs);
2119 if (res != WindowManagerImpl.ADD_OKAY) {
2120 return res;
2121 }
Romain Guy06882f82009-06-10 13:36:04 -07002122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 boolean reportNewConfig = false;
2124 WindowState attachedWindow = null;
2125 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002126 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002130 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 }
Romain Guy06882f82009-06-10 13:36:04 -07002132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002133 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2136 }
2137
2138 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002139 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002141 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 + attrs.token + ". Aborting.");
2143 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2144 }
2145 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2146 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002147 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 + attrs.token + ". Aborting.");
2149 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2150 }
2151 }
2152
2153 boolean addToken = false;
2154 WindowToken token = mTokenMap.get(attrs.token);
2155 if (token == null) {
2156 if (attrs.type >= FIRST_APPLICATION_WINDOW
2157 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002158 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 + attrs.token + ". Aborting.");
2160 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2161 }
2162 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002163 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 + attrs.token + ". Aborting.");
2165 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2166 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002167 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002168 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002169 + attrs.token + ". Aborting.");
2170 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 token = new WindowToken(attrs.token, -1, false);
2173 addToken = true;
2174 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2175 && attrs.type <= LAST_APPLICATION_WINDOW) {
2176 AppWindowToken atoken = token.appWindowToken;
2177 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002178 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002179 + token + ". Aborting.");
2180 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2181 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002182 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 + token + ". Aborting.");
2184 return WindowManagerImpl.ADD_APP_EXITING;
2185 }
2186 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2187 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002188 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2190 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2191 }
2192 } else if (attrs.type == TYPE_INPUT_METHOD) {
2193 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002194 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 + attrs.token + ". Aborting.");
2196 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2197 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002198 } else if (attrs.type == TYPE_WALLPAPER) {
2199 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002200 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002201 + attrs.token + ". Aborting.");
2202 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 }
2205
2206 win = new WindowState(session, client, token,
2207 attachedWindow, attrs, viewVisibility);
2208 if (win.mDeathRecipient == null) {
2209 // Client has apparently died, so there is no reason to
2210 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002211 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002212 + " that is dead, aborting.");
2213 return WindowManagerImpl.ADD_APP_EXITING;
2214 }
2215
2216 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 res = mPolicy.prepareAddWindowLw(win, attrs);
2219 if (res != WindowManagerImpl.ADD_OKAY) {
2220 return res;
2221 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002222
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002223 if (outInputChannel != null) {
2224 String name = win.makeInputChannelName();
2225 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2226 win.mInputChannel = inputChannels[0];
2227 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2228
2229 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002230 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231
2232 // From now on, no exceptions or errors allowed!
2233
2234 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002235
Dianne Hackborn5132b372010-07-29 12:51:35 -07002236 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002238 if (addToken) {
2239 mTokenMap.put(attrs.token, token);
2240 mTokenList.add(token);
2241 }
2242 win.attach();
2243 mWindowMap.put(client.asBinder(), win);
2244
2245 if (attrs.type == TYPE_APPLICATION_STARTING &&
2246 token.appWindowToken != null) {
2247 token.appWindowToken.startingWindow = win;
2248 }
2249
2250 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 if (attrs.type == TYPE_INPUT_METHOD) {
2253 mInputMethodWindow = win;
2254 addInputMethodWindowToListLocked(win);
2255 imMayMove = false;
2256 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2257 mInputMethodDialogs.add(win);
2258 addWindowToListInOrderLocked(win, true);
2259 adjustInputMethodDialogsLocked();
2260 imMayMove = false;
2261 } else {
2262 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002263 if (attrs.type == TYPE_WALLPAPER) {
2264 mLastWallpaperTimeoutTime = 0;
2265 adjustWallpaperWindowsLocked();
2266 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002267 adjustWallpaperWindowsLocked();
2268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 }
Romain Guy06882f82009-06-10 13:36:04 -07002270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 if (mInTouchMode) {
2276 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2277 }
2278 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2279 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2280 }
Romain Guy06882f82009-06-10 13:36:04 -07002281
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002282 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002284 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2285 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 imMayMove = false;
2287 }
2288 }
Romain Guy06882f82009-06-10 13:36:04 -07002289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002291 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 }
Romain Guy06882f82009-06-10 13:36:04 -07002293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 assignLayersLocked();
2295 // Don't do layout here, the window must call
2296 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 //dump();
2299
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002300 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002301 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002302 }
Jeff Brown349703e2010-06-22 01:27:15 -07002303
Joe Onorato8a9b2202010-02-26 18:56:32 -08002304 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 TAG, "New client " + client.asBinder()
2306 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002307
2308 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2309 reportNewConfig = true;
2310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 }
2312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 if (reportNewConfig) {
2314 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 return res;
2320 }
Romain Guy06882f82009-06-10 13:36:04 -07002321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 public void removeWindow(Session session, IWindow client) {
2323 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002324 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 if (win == null) {
2326 return;
2327 }
2328 removeWindowLocked(session, win);
2329 }
2330 }
Romain Guy06882f82009-06-10 13:36:04 -07002331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 public void removeWindowLocked(Session session, WindowState win) {
2333
Joe Onorato8a9b2202010-02-26 18:56:32 -08002334 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 TAG, "Remove " + win + " client="
2336 + Integer.toHexString(System.identityHashCode(
2337 win.mClient.asBinder()))
2338 + ", surface=" + win.mSurface);
2339
2340 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002341
2342 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002343
Joe Onorato8a9b2202010-02-26 18:56:32 -08002344 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2346 + " mExiting=" + win.mExiting
2347 + " isAnimating=" + win.isAnimating()
2348 + " app-animation="
2349 + (win.mAppToken != null ? win.mAppToken.animation : null)
2350 + " inPendingTransaction="
2351 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2352 + " mDisplayFrozen=" + mDisplayFrozen);
2353 // Visibility of the removed window. Will be used later to update orientation later on.
2354 boolean wasVisible = false;
2355 // First, see if we need to run an animation. If we do, we have
2356 // to hold off on removing the window until the animation is done.
2357 // If the display is frozen, just remove immediately, since the
2358 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002359 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002360 // If we are not currently running the exit animation, we
2361 // need to see about starting one.
2362 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2365 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2366 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2367 }
2368 // Try starting an animation.
2369 if (applyAnimationLocked(win, transit, false)) {
2370 win.mExiting = true;
2371 }
2372 }
2373 if (win.mExiting || win.isAnimating()) {
2374 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002375 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 win.mExiting = true;
2377 win.mRemoveOnExit = true;
2378 mLayoutNeeded = true;
2379 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2380 performLayoutAndPlaceSurfacesLocked();
2381 if (win.mAppToken != null) {
2382 win.mAppToken.updateReportedVisibilityLocked();
2383 }
2384 //dump();
2385 Binder.restoreCallingIdentity(origId);
2386 return;
2387 }
2388 }
2389
2390 removeWindowInnerLocked(session, win);
2391 // Removing a visible window will effect the computed orientation
2392 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002393 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002394 != mForcedAppOrientation
2395 && updateOrientationFromAppTokensLocked()) {
2396 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 }
2398 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2399 Binder.restoreCallingIdentity(origId);
2400 }
Romain Guy06882f82009-06-10 13:36:04 -07002401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 if (mInputMethodTarget == win) {
2406 moveInputMethodWindowsIfNeededLocked(false);
2407 }
Romain Guy06882f82009-06-10 13:36:04 -07002408
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002409 if (false) {
2410 RuntimeException e = new RuntimeException("here");
2411 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002412 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002413 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 mPolicy.removeWindowLw(win);
2416 win.removeLocked();
2417
2418 mWindowMap.remove(win.mClient.asBinder());
2419 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002420 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002421 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422
2423 if (mInputMethodWindow == win) {
2424 mInputMethodWindow = null;
2425 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2426 mInputMethodDialogs.remove(win);
2427 }
Romain Guy06882f82009-06-10 13:36:04 -07002428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 final WindowToken token = win.mToken;
2430 final AppWindowToken atoken = win.mAppToken;
2431 token.windows.remove(win);
2432 if (atoken != null) {
2433 atoken.allAppWindows.remove(win);
2434 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002435 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 TAG, "**** Removing window " + win + ": count="
2437 + token.windows.size());
2438 if (token.windows.size() == 0) {
2439 if (!token.explicit) {
2440 mTokenMap.remove(token.token);
2441 mTokenList.remove(token);
2442 } else if (atoken != null) {
2443 atoken.firstWindowDrawn = false;
2444 }
2445 }
2446
2447 if (atoken != null) {
2448 if (atoken.startingWindow == win) {
2449 atoken.startingWindow = null;
2450 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2451 // If this is the last window and we had requested a starting
2452 // transition window, well there is no point now.
2453 atoken.startingData = null;
2454 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2455 // If this is the last window except for a starting transition
2456 // window, we need to get rid of the starting transition.
2457 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002458 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 + ": no more real windows");
2460 }
2461 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2462 mH.sendMessage(m);
2463 }
2464 }
Romain Guy06882f82009-06-10 13:36:04 -07002465
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002466 if (win.mAttrs.type == TYPE_WALLPAPER) {
2467 mLastWallpaperTimeoutTime = 0;
2468 adjustWallpaperWindowsLocked();
2469 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002470 adjustWallpaperWindowsLocked();
2471 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 if (!mInLayout) {
2474 assignLayersLocked();
2475 mLayoutNeeded = true;
2476 performLayoutAndPlaceSurfacesLocked();
2477 if (win.mAppToken != null) {
2478 win.mAppToken.updateReportedVisibilityLocked();
2479 }
2480 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002481
2482 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 }
2484
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002485 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2486 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2487 + ": " + msg + " / " + w.mAttrs.getTitle();
2488 if (where != null) {
2489 Slog.i(TAG, str, where);
2490 } else {
2491 Slog.i(TAG, str);
2492 }
2493 }
2494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2496 long origId = Binder.clearCallingIdentity();
2497 try {
2498 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002499 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002500 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002501 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 Surface.openTransaction();
2503 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002504 if (SHOW_TRANSACTIONS) logSurface(w,
2505 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 w.mSurface.setTransparentRegionHint(region);
2507 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002508 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 Surface.closeTransaction();
2510 }
2511 }
2512 }
2513 } finally {
2514 Binder.restoreCallingIdentity(origId);
2515 }
2516 }
2517
2518 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002519 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 Rect visibleInsets) {
2521 long origId = Binder.clearCallingIdentity();
2522 try {
2523 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002524 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525 if (w != null) {
2526 w.mGivenInsetsPending = false;
2527 w.mGivenContentInsets.set(contentInsets);
2528 w.mGivenVisibleInsets.set(visibleInsets);
2529 w.mTouchableInsets = touchableInsets;
2530 mLayoutNeeded = true;
2531 performLayoutAndPlaceSurfacesLocked();
2532 }
2533 }
2534 } finally {
2535 Binder.restoreCallingIdentity(origId);
2536 }
2537 }
Romain Guy06882f82009-06-10 13:36:04 -07002538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 public void getWindowDisplayFrame(Session session, IWindow client,
2540 Rect outDisplayFrame) {
2541 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002542 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543 if (win == null) {
2544 outDisplayFrame.setEmpty();
2545 return;
2546 }
2547 outDisplayFrame.set(win.mDisplayFrame);
2548 }
2549 }
2550
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002551 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2552 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002553 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2554 window.mWallpaperX = x;
2555 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002556 window.mWallpaperXStep = xStep;
2557 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002558 if (updateWallpaperOffsetLocked(window, true)) {
2559 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002560 }
2561 }
2562 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002563
Dianne Hackborn75804932009-10-20 20:15:20 -07002564 void wallpaperCommandComplete(IBinder window, Bundle result) {
2565 synchronized (mWindowMap) {
2566 if (mWaitingOnWallpaper != null &&
2567 mWaitingOnWallpaper.mClient.asBinder() == window) {
2568 mWaitingOnWallpaper = null;
2569 mWindowMap.notifyAll();
2570 }
2571 }
2572 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002573
Dianne Hackborn75804932009-10-20 20:15:20 -07002574 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2575 String action, int x, int y, int z, Bundle extras, boolean sync) {
2576 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2577 || window == mUpperWallpaperTarget) {
2578 boolean doWait = sync;
2579 int curTokenIndex = mWallpaperTokens.size();
2580 while (curTokenIndex > 0) {
2581 curTokenIndex--;
2582 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2583 int curWallpaperIndex = token.windows.size();
2584 while (curWallpaperIndex > 0) {
2585 curWallpaperIndex--;
2586 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2587 try {
2588 wallpaper.mClient.dispatchWallpaperCommand(action,
2589 x, y, z, extras, sync);
2590 // We only want to be synchronous with one wallpaper.
2591 sync = false;
2592 } catch (RemoteException e) {
2593 }
2594 }
2595 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002596
Dianne Hackborn75804932009-10-20 20:15:20 -07002597 if (doWait) {
2598 // XXX Need to wait for result.
2599 }
2600 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002601
Dianne Hackborn75804932009-10-20 20:15:20 -07002602 return null;
2603 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 public int relayoutWindow(Session session, IWindow client,
2606 WindowManager.LayoutParams attrs, int requestedWidth,
2607 int requestedHeight, int viewVisibility, boolean insetsPending,
2608 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002609 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 boolean displayed = false;
2611 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002612 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002616 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 if (win == null) {
2618 return 0;
2619 }
2620 win.mRequestedWidth = requestedWidth;
2621 win.mRequestedHeight = requestedHeight;
2622
2623 if (attrs != null) {
2624 mPolicy.adjustWindowParamsLw(attrs);
2625 }
Romain Guy06882f82009-06-10 13:36:04 -07002626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 int attrChanges = 0;
2628 int flagChanges = 0;
2629 if (attrs != null) {
2630 flagChanges = win.mAttrs.flags ^= attrs.flags;
2631 attrChanges = win.mAttrs.copyFrom(attrs);
2632 }
2633
Joe Onorato8a9b2202010-02-26 18:56:32 -08002634 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002635
2636 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2637 win.mAlpha = attrs.alpha;
2638 }
2639
2640 final boolean scaledWindow =
2641 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2642
2643 if (scaledWindow) {
2644 // requested{Width|Height} Surface's physical size
2645 // attrs.{width|height} Size on screen
2646 win.mHScale = (attrs.width != requestedWidth) ?
2647 (attrs.width / (float)requestedWidth) : 1.0f;
2648 win.mVScale = (attrs.height != requestedHeight) ?
2649 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002650 } else {
2651 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 }
2653
2654 boolean imMayMove = (flagChanges&(
2655 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2656 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 boolean focusMayChange = win.mViewVisibility != viewVisibility
2659 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2660 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002661
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002662 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2663 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 win.mRelayoutCalled = true;
2666 final int oldVisibility = win.mViewVisibility;
2667 win.mViewVisibility = viewVisibility;
2668 if (viewVisibility == View.VISIBLE &&
2669 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2670 displayed = !win.isVisibleLw();
2671 if (win.mExiting) {
2672 win.mExiting = false;
2673 win.mAnimation = null;
2674 }
2675 if (win.mDestroying) {
2676 win.mDestroying = false;
2677 mDestroySurface.remove(win);
2678 }
2679 if (oldVisibility == View.GONE) {
2680 win.mEnterAnimationPending = true;
2681 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002682 if (displayed) {
2683 if (win.mSurface != null && !win.mDrawPending
2684 && !win.mCommitDrawPending && !mDisplayFrozen
2685 && mPolicy.isScreenOn()) {
2686 applyEnterAnimationLocked(win);
2687 }
2688 if ((win.mAttrs.flags
2689 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2690 if (DEBUG_VISIBILITY) Slog.v(TAG,
2691 "Relayout window turning screen on: " + win);
2692 win.mTurnOnScreen = true;
2693 }
2694 int diff = 0;
2695 if (win.mConfiguration != mCurConfiguration
2696 && (win.mConfiguration == null
2697 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2698 win.mConfiguration = mCurConfiguration;
2699 if (DEBUG_CONFIGURATION) {
2700 Slog.i(TAG, "Window " + win + " visible with new config: "
2701 + win.mConfiguration + " / 0x"
2702 + Integer.toHexString(diff));
2703 }
2704 outConfig.setTo(mCurConfiguration);
2705 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2708 // To change the format, we need to re-build the surface.
2709 win.destroySurfaceLocked();
2710 displayed = true;
2711 }
2712 try {
2713 Surface surface = win.createSurfaceLocked();
2714 if (surface != null) {
2715 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002716 win.mReportDestroySurface = false;
2717 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002719 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002721 // For some reason there isn't a surface. Clear the
2722 // caller's object so they see the same state.
2723 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002726 mInputMonitor.updateInputWindowsLw();
2727
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002729 + client + " (" + win.mAttrs.getTitle() + ")",
2730 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 Binder.restoreCallingIdentity(origId);
2732 return 0;
2733 }
2734 if (displayed) {
2735 focusMayChange = true;
2736 }
2737 if (win.mAttrs.type == TYPE_INPUT_METHOD
2738 && mInputMethodWindow == null) {
2739 mInputMethodWindow = win;
2740 imMayMove = true;
2741 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002742 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2743 && win.mAppToken != null
2744 && win.mAppToken.startingWindow != null) {
2745 // Special handling of starting window over the base
2746 // window of the app: propagate lock screen flags to it,
2747 // to provide the correct semantics while starting.
2748 final int mask =
2749 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002750 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2751 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002752 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2753 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 } else {
2756 win.mEnterAnimationPending = false;
2757 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002758 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002759 + ": mExiting=" + win.mExiting
2760 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002761 // If we are not currently running the exit animation, we
2762 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002763 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 // Try starting an animation; if there isn't one, we
2765 // can destroy the surface right away.
2766 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2767 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2768 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2769 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002770 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002772 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002773 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 } else if (win.isAnimating()) {
2775 // Currently in a hide animation... turn this into
2776 // an exit.
2777 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002778 } else if (win == mWallpaperTarget) {
2779 // If the wallpaper is currently behind this
2780 // window, we need to change both of them inside
2781 // of a transaction to avoid artifacts.
2782 win.mExiting = true;
2783 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 } else {
2785 if (mInputMethodWindow == win) {
2786 mInputMethodWindow = null;
2787 }
2788 win.destroySurfaceLocked();
2789 }
2790 }
2791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002792
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002793 if (win.mSurface == null || (win.getAttrs().flags
2794 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2795 || win.mSurfacePendingDestroy) {
2796 // We are being called from a local process, which
2797 // means outSurface holds its current surface. Ensure the
2798 // surface object is cleared, but we don't want it actually
2799 // destroyed at this point.
2800 win.mSurfacePendingDestroy = false;
2801 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002802 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002803 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002804 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002805 "Keeping surface, will report destroy: " + win);
2806 win.mReportDestroySurface = true;
2807 outSurface.copyFrom(win.mSurface);
2808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002809 }
2810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002811 if (focusMayChange) {
2812 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2813 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 imMayMove = false;
2815 }
2816 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2817 }
Romain Guy06882f82009-06-10 13:36:04 -07002818
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002819 // updateFocusedWindowLocked() already assigned layers so we only need to
2820 // reassign them at this point if the IM window state gets shuffled
2821 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002824 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2825 // Little hack here -- we -should- be able to rely on the
2826 // function to return true if the IME has moved and needs
2827 // its layer recomputed. However, if the IME was hidden
2828 // and isn't actually moved in the list, its layer may be
2829 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 assignLayers = true;
2831 }
2832 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002833 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002834 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002835 assignLayers = true;
2836 }
2837 }
Romain Guy06882f82009-06-10 13:36:04 -07002838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 mLayoutNeeded = true;
2840 win.mGivenInsetsPending = insetsPending;
2841 if (assignLayers) {
2842 assignLayersLocked();
2843 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002844 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002846 if (displayed && win.mIsWallpaper) {
2847 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002848 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002850 if (win.mAppToken != null) {
2851 win.mAppToken.updateReportedVisibilityLocked();
2852 }
2853 outFrame.set(win.mFrame);
2854 outContentInsets.set(win.mContentInsets);
2855 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002856 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002858 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 + ", requestedHeight=" + requestedHeight
2860 + ", viewVisibility=" + viewVisibility
2861 + "\nRelayout returning frame=" + outFrame
2862 + ", surface=" + outSurface);
2863
Joe Onorato8a9b2202010-02-26 18:56:32 -08002864 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2866
2867 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002868
2869 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 }
2871
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002872 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 sendNewConfiguration();
2874 }
Romain Guy06882f82009-06-10 13:36:04 -07002875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2879 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2880 }
2881
2882 public void finishDrawingWindow(Session session, IWindow client) {
2883 final long origId = Binder.clearCallingIdentity();
2884 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002885 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002887 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2888 adjustWallpaperWindowsLocked();
2889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 mLayoutNeeded = true;
2891 performLayoutAndPlaceSurfacesLocked();
2892 }
2893 }
2894 Binder.restoreCallingIdentity(origId);
2895 }
2896
2897 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002898 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 + (lp != null ? lp.packageName : null)
2900 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2901 if (lp != null && lp.windowAnimations != 0) {
2902 // If this is a system resource, don't try to load it from the
2903 // application resources. It is nice to avoid loading application
2904 // resources if we can.
2905 String packageName = lp.packageName != null ? lp.packageName : "android";
2906 int resId = lp.windowAnimations;
2907 if ((resId&0xFF000000) == 0x01000000) {
2908 packageName = "android";
2909 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002910 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 + packageName);
2912 return AttributeCache.instance().get(packageName, resId,
2913 com.android.internal.R.styleable.WindowAnimation);
2914 }
2915 return null;
2916 }
Romain Guy06882f82009-06-10 13:36:04 -07002917
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002918 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002919 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002920 + packageName + " resId=0x" + Integer.toHexString(resId));
2921 if (packageName != null) {
2922 if ((resId&0xFF000000) == 0x01000000) {
2923 packageName = "android";
2924 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002925 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002926 + packageName);
2927 return AttributeCache.instance().get(packageName, resId,
2928 com.android.internal.R.styleable.WindowAnimation);
2929 }
2930 return null;
2931 }
2932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002933 private void applyEnterAnimationLocked(WindowState win) {
2934 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2935 if (win.mEnterAnimationPending) {
2936 win.mEnterAnimationPending = false;
2937 transit = WindowManagerPolicy.TRANSIT_ENTER;
2938 }
2939
2940 applyAnimationLocked(win, transit, true);
2941 }
2942
2943 private boolean applyAnimationLocked(WindowState win,
2944 int transit, boolean isEntrance) {
2945 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2946 // If we are trying to apply an animation, but already running
2947 // an animation of the same type, then just leave that one alone.
2948 return true;
2949 }
Romain Guy06882f82009-06-10 13:36:04 -07002950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 // Only apply an animation if the display isn't frozen. If it is
2952 // frozen, there is no reason to animate and it can cause strange
2953 // artifacts when we unfreeze the display if some different animation
2954 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002955 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 int anim = mPolicy.selectAnimationLw(win, transit);
2957 int attr = -1;
2958 Animation a = null;
2959 if (anim != 0) {
2960 a = AnimationUtils.loadAnimation(mContext, anim);
2961 } else {
2962 switch (transit) {
2963 case WindowManagerPolicy.TRANSIT_ENTER:
2964 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2965 break;
2966 case WindowManagerPolicy.TRANSIT_EXIT:
2967 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2968 break;
2969 case WindowManagerPolicy.TRANSIT_SHOW:
2970 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2971 break;
2972 case WindowManagerPolicy.TRANSIT_HIDE:
2973 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2974 break;
2975 }
2976 if (attr >= 0) {
2977 a = loadAnimation(win.mAttrs, attr);
2978 }
2979 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002980 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002981 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2982 + " mAnimation=" + win.mAnimation
2983 + " isEntrance=" + isEntrance);
2984 if (a != null) {
2985 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002986 RuntimeException e = null;
2987 if (!HIDE_STACK_CRAWLS) {
2988 e = new RuntimeException();
2989 e.fillInStackTrace();
2990 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002991 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993 win.setAnimation(a);
2994 win.mAnimationIsEntrance = isEntrance;
2995 }
2996 } else {
2997 win.clearAnimation();
2998 }
2999
3000 return win.mAnimation != null;
3001 }
3002
3003 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3004 int anim = 0;
3005 Context context = mContext;
3006 if (animAttr >= 0) {
3007 AttributeCache.Entry ent = getCachedAnimations(lp);
3008 if (ent != null) {
3009 context = ent.context;
3010 anim = ent.array.getResourceId(animAttr, 0);
3011 }
3012 }
3013 if (anim != 0) {
3014 return AnimationUtils.loadAnimation(context, anim);
3015 }
3016 return null;
3017 }
Romain Guy06882f82009-06-10 13:36:04 -07003018
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003019 private Animation loadAnimation(String packageName, int resId) {
3020 int anim = 0;
3021 Context context = mContext;
3022 if (resId >= 0) {
3023 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3024 if (ent != null) {
3025 context = ent.context;
3026 anim = resId;
3027 }
3028 }
3029 if (anim != 0) {
3030 return AnimationUtils.loadAnimation(context, anim);
3031 }
3032 return null;
3033 }
3034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 private boolean applyAnimationLocked(AppWindowToken wtoken,
3036 WindowManager.LayoutParams lp, int transit, boolean enter) {
3037 // Only apply an animation if the display isn't frozen. If it is
3038 // frozen, there is no reason to animate and it can cause strange
3039 // artifacts when we unfreeze the display if some different animation
3040 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003041 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003042 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003043 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003044 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003045 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003046 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003047 } else if (mNextAppTransitionPackage != null) {
3048 a = loadAnimation(mNextAppTransitionPackage, enter ?
3049 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003050 } else {
3051 int animAttr = 0;
3052 switch (transit) {
3053 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3054 animAttr = enter
3055 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3056 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3057 break;
3058 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3059 animAttr = enter
3060 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3061 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3062 break;
3063 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3064 animAttr = enter
3065 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3066 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3067 break;
3068 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3069 animAttr = enter
3070 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3071 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3072 break;
3073 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3074 animAttr = enter
3075 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3076 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3077 break;
3078 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3079 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003080 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003081 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3082 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003083 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003084 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003085 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3086 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003087 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003088 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003089 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003090 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3091 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3092 break;
3093 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3094 animAttr = enter
3095 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3096 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3097 break;
3098 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3099 animAttr = enter
3100 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3101 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003102 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003103 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003104 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003105 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003106 + " anim=" + a
3107 + " animAttr=0x" + Integer.toHexString(animAttr)
3108 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 if (a != null) {
3111 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003112 RuntimeException e = null;
3113 if (!HIDE_STACK_CRAWLS) {
3114 e = new RuntimeException();
3115 e.fillInStackTrace();
3116 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003117 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 }
3119 wtoken.setAnimation(a);
3120 }
3121 } else {
3122 wtoken.clearAnimation();
3123 }
3124
3125 return wtoken.animation != null;
3126 }
3127
3128 // -------------------------------------------------------------
3129 // Application Window Tokens
3130 // -------------------------------------------------------------
3131
3132 public void validateAppTokens(List tokens) {
3133 int v = tokens.size()-1;
3134 int m = mAppTokens.size()-1;
3135 while (v >= 0 && m >= 0) {
3136 AppWindowToken wtoken = mAppTokens.get(m);
3137 if (wtoken.removed) {
3138 m--;
3139 continue;
3140 }
3141 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3144 }
3145 v--;
3146 m--;
3147 }
3148 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003149 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003150 v--;
3151 }
3152 while (m >= 0) {
3153 AppWindowToken wtoken = mAppTokens.get(m);
3154 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003155 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 }
3157 m--;
3158 }
3159 }
3160
3161 boolean checkCallingPermission(String permission, String func) {
3162 // Quick check: if the calling permission is me, it's all okay.
3163 if (Binder.getCallingPid() == Process.myPid()) {
3164 return true;
3165 }
Romain Guy06882f82009-06-10 13:36:04 -07003166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003167 if (mContext.checkCallingPermission(permission)
3168 == PackageManager.PERMISSION_GRANTED) {
3169 return true;
3170 }
3171 String msg = "Permission Denial: " + func + " from pid="
3172 + Binder.getCallingPid()
3173 + ", uid=" + Binder.getCallingUid()
3174 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003175 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 return false;
3177 }
Romain Guy06882f82009-06-10 13:36:04 -07003178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 AppWindowToken findAppWindowToken(IBinder token) {
3180 WindowToken wtoken = mTokenMap.get(token);
3181 if (wtoken == null) {
3182 return null;
3183 }
3184 return wtoken.appWindowToken;
3185 }
Romain Guy06882f82009-06-10 13:36:04 -07003186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 public void addWindowToken(IBinder token, int type) {
3188 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3189 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003190 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003191 }
Romain Guy06882f82009-06-10 13:36:04 -07003192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 synchronized(mWindowMap) {
3194 WindowToken wtoken = mTokenMap.get(token);
3195 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003196 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003197 return;
3198 }
3199 wtoken = new WindowToken(token, type, true);
3200 mTokenMap.put(token, wtoken);
3201 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003202 if (type == TYPE_WALLPAPER) {
3203 mWallpaperTokens.add(wtoken);
3204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003205 }
3206 }
Romain Guy06882f82009-06-10 13:36:04 -07003207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 public void removeWindowToken(IBinder token) {
3209 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3210 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003211 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 }
3213
3214 final long origId = Binder.clearCallingIdentity();
3215 synchronized(mWindowMap) {
3216 WindowToken wtoken = mTokenMap.remove(token);
3217 mTokenList.remove(wtoken);
3218 if (wtoken != null) {
3219 boolean delayed = false;
3220 if (!wtoken.hidden) {
3221 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003223 final int N = wtoken.windows.size();
3224 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 for (int i=0; i<N; i++) {
3227 WindowState win = wtoken.windows.get(i);
3228
3229 if (win.isAnimating()) {
3230 delayed = true;
3231 }
Romain Guy06882f82009-06-10 13:36:04 -07003232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 if (win.isVisibleNow()) {
3234 applyAnimationLocked(win,
3235 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 changed = true;
3237 }
3238 }
3239
3240 if (changed) {
3241 mLayoutNeeded = true;
3242 performLayoutAndPlaceSurfacesLocked();
3243 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3244 }
Romain Guy06882f82009-06-10 13:36:04 -07003245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003246 if (delayed) {
3247 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003248 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3249 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250 }
3251 }
Romain Guy06882f82009-06-10 13:36:04 -07003252
Jeff Brownc5ed5912010-07-14 18:48:53 -07003253 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003255 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 }
3257 }
3258 Binder.restoreCallingIdentity(origId);
3259 }
3260
3261 public void addAppToken(int addPos, IApplicationToken token,
3262 int groupId, int requestedOrientation, boolean fullscreen) {
3263 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3264 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003265 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003266 }
Jeff Brown349703e2010-06-22 01:27:15 -07003267
3268 // Get the dispatching timeout here while we are not holding any locks so that it
3269 // can be cached by the AppWindowToken. The timeout value is used later by the
3270 // input dispatcher in code that does hold locks. If we did not cache the value
3271 // here we would run the chance of introducing a deadlock between the window manager
3272 // (which holds locks while updating the input dispatcher state) and the activity manager
3273 // (which holds locks while querying the application token).
3274 long inputDispatchingTimeoutNanos;
3275 try {
3276 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3277 } catch (RemoteException ex) {
3278 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3279 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3280 }
Romain Guy06882f82009-06-10 13:36:04 -07003281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 synchronized(mWindowMap) {
3283 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3284 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003285 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003286 return;
3287 }
3288 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003289 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 wtoken.groupId = groupId;
3291 wtoken.appFullscreen = fullscreen;
3292 wtoken.requestedOrientation = requestedOrientation;
3293 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003294 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003295 mTokenMap.put(token.asBinder(), wtoken);
3296 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 // Application tokens start out hidden.
3299 wtoken.hidden = true;
3300 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 //dump();
3303 }
3304 }
Romain Guy06882f82009-06-10 13:36:04 -07003305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 public void setAppGroupId(IBinder token, int groupId) {
3307 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3308 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003309 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 }
3311
3312 synchronized(mWindowMap) {
3313 AppWindowToken wtoken = findAppWindowToken(token);
3314 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003315 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 return;
3317 }
3318 wtoken.groupId = groupId;
3319 }
3320 }
Romain Guy06882f82009-06-10 13:36:04 -07003321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 public int getOrientationFromWindowsLocked() {
3323 int pos = mWindows.size() - 1;
3324 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003325 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 pos--;
3327 if (wtoken.mAppToken != null) {
3328 // We hit an application window. so the orientation will be determined by the
3329 // app window. No point in continuing further.
3330 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3331 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003332 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003333 continue;
3334 }
3335 int req = wtoken.mAttrs.screenOrientation;
3336 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3337 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3338 continue;
3339 } else {
3340 return req;
3341 }
3342 }
3343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3344 }
Romain Guy06882f82009-06-10 13:36:04 -07003345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003347 int pos = mAppTokens.size() - 1;
3348 int curGroup = 0;
3349 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3350 boolean findingBehind = false;
3351 boolean haveGroup = false;
3352 boolean lastFullscreen = false;
3353 while (pos >= 0) {
3354 AppWindowToken wtoken = mAppTokens.get(pos);
3355 pos--;
3356 // if we're about to tear down this window and not seek for
3357 // the behind activity, don't use it for orientation
3358 if (!findingBehind
3359 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3360 continue;
3361 }
3362
3363 if (!haveGroup) {
3364 // We ignore any hidden applications on the top.
3365 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003366 continue;
3367 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003368 haveGroup = true;
3369 curGroup = wtoken.groupId;
3370 lastOrientation = wtoken.requestedOrientation;
3371 } else if (curGroup != wtoken.groupId) {
3372 // If we have hit a new application group, and the bottom
3373 // of the previous group didn't explicitly say to use
3374 // the orientation behind it, and the last app was
3375 // full screen, then we'll stick with the
3376 // user's orientation.
3377 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3378 && lastFullscreen) {
3379 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003382 int or = wtoken.requestedOrientation;
3383 // If this application is fullscreen, and didn't explicitly say
3384 // to use the orientation behind it, then just take whatever
3385 // orientation it has and ignores whatever is under it.
3386 lastFullscreen = wtoken.appFullscreen;
3387 if (lastFullscreen
3388 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3389 return or;
3390 }
3391 // If this application has requested an explicit orientation,
3392 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003393 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3394 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003395 return or;
3396 }
3397 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3398 }
3399 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 }
Romain Guy06882f82009-06-10 13:36:04 -07003401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003403 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003404 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3405 "updateOrientationFromAppTokens()")) {
3406 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3407 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003408
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003409 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003411
3412 synchronized(mWindowMap) {
3413 if (updateOrientationFromAppTokensLocked()) {
3414 if (freezeThisOneIfNeeded != null) {
3415 AppWindowToken wtoken = findAppWindowToken(
3416 freezeThisOneIfNeeded);
3417 if (wtoken != null) {
3418 startAppFreezingScreenLocked(wtoken,
3419 ActivityInfo.CONFIG_ORIENTATION);
3420 }
3421 }
3422 config = computeNewConfigurationLocked();
3423
3424 } else if (currentConfig != null) {
3425 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003426 // state mismatches the activity manager's, update it,
3427 // disregarding font scale, which should remain set to
3428 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003429 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003430 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003431 if (computeNewConfigurationLocked(mTempConfiguration)) {
3432 if (currentConfig.diff(mTempConfiguration) != 0) {
3433 mWaitingForConfig = true;
3434 mLayoutNeeded = true;
3435 startFreezingDisplayLocked();
3436 config = new Configuration(mTempConfiguration);
3437 }
3438 }
3439 }
3440 }
3441
Dianne Hackborncfaef692009-06-15 14:24:44 -07003442 Binder.restoreCallingIdentity(ident);
3443 return config;
3444 }
3445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003447 * Determine the new desired orientation of the display, returning
3448 * a non-null new Configuration if it has changed from the current
3449 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3450 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3451 * SCREEN. This will typically be done for you if you call
3452 * sendNewConfiguration().
3453 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 * The orientation is computed from non-application windows first. If none of
3455 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003456 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003457 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3458 * android.os.IBinder)
3459 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003460 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003461 if (mDisplayFrozen) {
3462 // If the display is frozen, some activities may be in the middle
3463 // of restarting, and thus have removed their old window. If the
3464 // window has the flag to hide the lock screen, then the lock screen
3465 // can re-appear and inflict its own orientation on us. Keep the
3466 // orientation stable until this all settles down.
3467 return false;
3468 }
3469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 long ident = Binder.clearCallingIdentity();
3472 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003473 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 mForcedAppOrientation = req;
3477 //send a message to Policy indicating orientation change to take
3478 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003479 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003480 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3481 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3482 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 }
3484 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003485
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003486 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 } finally {
3488 Binder.restoreCallingIdentity(ident);
3489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 }
Romain Guy06882f82009-06-10 13:36:04 -07003491
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003492 int computeForcedAppOrientationLocked() {
3493 int req = getOrientationFromWindowsLocked();
3494 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3495 req = getOrientationFromAppTokensLocked();
3496 }
3497 return req;
3498 }
Romain Guy06882f82009-06-10 13:36:04 -07003499
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003500 public void setNewConfiguration(Configuration config) {
3501 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3502 "setNewConfiguration()")) {
3503 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3504 }
3505
3506 synchronized(mWindowMap) {
3507 mCurConfiguration = new Configuration(config);
3508 mWaitingForConfig = false;
3509 performLayoutAndPlaceSurfacesLocked();
3510 }
3511 }
3512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3514 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3515 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003516 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 }
Romain Guy06882f82009-06-10 13:36:04 -07003518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 synchronized(mWindowMap) {
3520 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3521 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003522 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 return;
3524 }
Romain Guy06882f82009-06-10 13:36:04 -07003525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 wtoken.requestedOrientation = requestedOrientation;
3527 }
3528 }
Romain Guy06882f82009-06-10 13:36:04 -07003529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 public int getAppOrientation(IApplicationToken token) {
3531 synchronized(mWindowMap) {
3532 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3533 if (wtoken == null) {
3534 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3535 }
Romain Guy06882f82009-06-10 13:36:04 -07003536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 return wtoken.requestedOrientation;
3538 }
3539 }
Romain Guy06882f82009-06-10 13:36:04 -07003540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3542 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3543 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003544 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 }
3546
3547 synchronized(mWindowMap) {
3548 boolean changed = false;
3549 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003550 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 changed = mFocusedApp != null;
3552 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003553 if (changed) {
3554 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 } else {
3557 AppWindowToken newFocus = findAppWindowToken(token);
3558 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003559 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 return;
3561 }
3562 changed = mFocusedApp != newFocus;
3563 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003564 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003565 if (changed) {
3566 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
3569
3570 if (moveFocusNow && changed) {
3571 final long origId = Binder.clearCallingIdentity();
3572 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3573 Binder.restoreCallingIdentity(origId);
3574 }
3575 }
3576 }
3577
3578 public void prepareAppTransition(int transit) {
3579 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3580 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003581 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582 }
Romain Guy06882f82009-06-10 13:36:04 -07003583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003585 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 TAG, "Prepare app transition: transit=" + transit
3587 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003588 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003589 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3590 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003592 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3593 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3594 // Opening a new task always supersedes a close for the anim.
3595 mNextAppTransition = transit;
3596 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3597 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3598 // Opening a new activity always supersedes a close for the anim.
3599 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 }
3601 mAppTransitionReady = false;
3602 mAppTransitionTimeout = false;
3603 mStartingIconInTransition = false;
3604 mSkipAppTransitionAnimation = false;
3605 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3606 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3607 5000);
3608 }
3609 }
3610 }
3611
3612 public int getPendingAppTransition() {
3613 return mNextAppTransition;
3614 }
Romain Guy06882f82009-06-10 13:36:04 -07003615
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003616 public void overridePendingAppTransition(String packageName,
3617 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003618 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003619 mNextAppTransitionPackage = packageName;
3620 mNextAppTransitionEnter = enterAnim;
3621 mNextAppTransitionExit = exitAnim;
3622 }
3623 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 public void executeAppTransition() {
3626 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3627 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003628 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 }
Romain Guy06882f82009-06-10 13:36:04 -07003630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003632 if (DEBUG_APP_TRANSITIONS) {
3633 RuntimeException e = new RuntimeException("here");
3634 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003635 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003636 + mNextAppTransition, e);
3637 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003638 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 mAppTransitionReady = true;
3640 final long origId = Binder.clearCallingIdentity();
3641 performLayoutAndPlaceSurfacesLocked();
3642 Binder.restoreCallingIdentity(origId);
3643 }
3644 }
3645 }
3646
3647 public void setAppStartingWindow(IBinder token, String pkg,
3648 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
3649 IBinder transferFrom, boolean createIfNeeded) {
3650 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3651 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003652 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 }
3654
3655 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003656 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3658 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 AppWindowToken wtoken = findAppWindowToken(token);
3661 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003662 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 return;
3664 }
3665
3666 // If the display is frozen, we won't do anything until the
3667 // actual window is displayed so there is no reason to put in
3668 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003669 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 return;
3671 }
Romain Guy06882f82009-06-10 13:36:04 -07003672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 if (wtoken.startingData != null) {
3674 return;
3675 }
Romain Guy06882f82009-06-10 13:36:04 -07003676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 if (transferFrom != null) {
3678 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3679 if (ttoken != null) {
3680 WindowState startingWindow = ttoken.startingWindow;
3681 if (startingWindow != null) {
3682 if (mStartingIconInTransition) {
3683 // In this case, the starting icon has already
3684 // been displayed, so start letting windows get
3685 // shown immediately without any more transitions.
3686 mSkipAppTransitionAnimation = true;
3687 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003688 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003689 "Moving existing starting from " + ttoken
3690 + " to " + wtoken);
3691 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 // Transfer the starting window over to the new
3694 // token.
3695 wtoken.startingData = ttoken.startingData;
3696 wtoken.startingView = ttoken.startingView;
3697 wtoken.startingWindow = startingWindow;
3698 ttoken.startingData = null;
3699 ttoken.startingView = null;
3700 ttoken.startingWindow = null;
3701 ttoken.startingMoved = true;
3702 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003703 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003705 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003706 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003708 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 ttoken.windows.remove(startingWindow);
3710 ttoken.allAppWindows.remove(startingWindow);
3711 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 // Propagate other interesting state between the
3714 // tokens. If the old token is displayed, we should
3715 // immediately force the new one to be displayed. If
3716 // it is animating, we need to move that animation to
3717 // the new one.
3718 if (ttoken.allDrawn) {
3719 wtoken.allDrawn = true;
3720 }
3721 if (ttoken.firstWindowDrawn) {
3722 wtoken.firstWindowDrawn = true;
3723 }
3724 if (!ttoken.hidden) {
3725 wtoken.hidden = false;
3726 wtoken.hiddenRequested = false;
3727 wtoken.willBeHidden = false;
3728 }
3729 if (wtoken.clientHidden != ttoken.clientHidden) {
3730 wtoken.clientHidden = ttoken.clientHidden;
3731 wtoken.sendAppVisibilityToClients();
3732 }
3733 if (ttoken.animation != null) {
3734 wtoken.animation = ttoken.animation;
3735 wtoken.animating = ttoken.animating;
3736 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3737 ttoken.animation = null;
3738 ttoken.animLayerAdjustment = 0;
3739 wtoken.updateLayers();
3740 ttoken.updateLayers();
3741 }
Romain Guy06882f82009-06-10 13:36:04 -07003742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 mLayoutNeeded = true;
3745 performLayoutAndPlaceSurfacesLocked();
3746 Binder.restoreCallingIdentity(origId);
3747 return;
3748 } else if (ttoken.startingData != null) {
3749 // The previous app was getting ready to show a
3750 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003751 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 "Moving pending starting from " + ttoken
3753 + " to " + wtoken);
3754 wtoken.startingData = ttoken.startingData;
3755 ttoken.startingData = null;
3756 ttoken.startingMoved = true;
3757 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3758 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3759 // want to process the message ASAP, before any other queued
3760 // messages.
3761 mH.sendMessageAtFrontOfQueue(m);
3762 return;
3763 }
3764 }
3765 }
3766
3767 // There is no existing starting window, and the caller doesn't
3768 // want us to create one, so that's it!
3769 if (!createIfNeeded) {
3770 return;
3771 }
Romain Guy06882f82009-06-10 13:36:04 -07003772
Dianne Hackborn284ac932009-08-28 10:34:25 -07003773 // If this is a translucent or wallpaper window, then don't
3774 // show a starting window -- the current effect (a full-screen
3775 // opaque starting window that fades away to the real contents
3776 // when it is ready) does not work for this.
3777 if (theme != 0) {
3778 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3779 com.android.internal.R.styleable.Window);
3780 if (ent.array.getBoolean(
3781 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3782 return;
3783 }
3784 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003785 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3786 return;
3787 }
3788 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003789 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3790 return;
3791 }
3792 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 mStartingIconInTransition = true;
3795 wtoken.startingData = new StartingData(
3796 pkg, theme, nonLocalizedLabel,
3797 labelRes, icon);
3798 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3799 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3800 // want to process the message ASAP, before any other queued
3801 // messages.
3802 mH.sendMessageAtFrontOfQueue(m);
3803 }
3804 }
3805
3806 public void setAppWillBeHidden(IBinder token) {
3807 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3808 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003809 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 }
3811
3812 AppWindowToken wtoken;
3813
3814 synchronized(mWindowMap) {
3815 wtoken = findAppWindowToken(token);
3816 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003817 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 -08003818 return;
3819 }
3820 wtoken.willBeHidden = true;
3821 }
3822 }
Romain Guy06882f82009-06-10 13:36:04 -07003823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3825 boolean visible, int transit, boolean performLayout) {
3826 boolean delayed = false;
3827
3828 if (wtoken.clientHidden == visible) {
3829 wtoken.clientHidden = !visible;
3830 wtoken.sendAppVisibilityToClients();
3831 }
Romain Guy06882f82009-06-10 13:36:04 -07003832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 wtoken.willBeHidden = false;
3834 if (wtoken.hidden == visible) {
3835 final int N = wtoken.allAppWindows.size();
3836 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003837 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3839 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003842
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003843 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 if (wtoken.animation == sDummyAnimation) {
3845 wtoken.animation = null;
3846 }
3847 applyAnimationLocked(wtoken, lp, transit, visible);
3848 changed = true;
3849 if (wtoken.animation != null) {
3850 delayed = runningAppAnimation = true;
3851 }
3852 }
Romain Guy06882f82009-06-10 13:36:04 -07003853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 for (int i=0; i<N; i++) {
3855 WindowState win = wtoken.allAppWindows.get(i);
3856 if (win == wtoken.startingWindow) {
3857 continue;
3858 }
3859
3860 if (win.isAnimating()) {
3861 delayed = true;
3862 }
Romain Guy06882f82009-06-10 13:36:04 -07003863
Joe Onorato8a9b2202010-02-26 18:56:32 -08003864 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 //win.dump(" ");
3866 if (visible) {
3867 if (!win.isVisibleNow()) {
3868 if (!runningAppAnimation) {
3869 applyAnimationLocked(win,
3870 WindowManagerPolicy.TRANSIT_ENTER, true);
3871 }
3872 changed = true;
3873 }
3874 } else if (win.isVisibleNow()) {
3875 if (!runningAppAnimation) {
3876 applyAnimationLocked(win,
3877 WindowManagerPolicy.TRANSIT_EXIT, false);
3878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 changed = true;
3880 }
3881 }
3882
3883 wtoken.hidden = wtoken.hiddenRequested = !visible;
3884 if (!visible) {
3885 unsetAppFreezingScreenLocked(wtoken, true, true);
3886 } else {
3887 // If we are being set visible, and the starting window is
3888 // not yet displayed, then make sure it doesn't get displayed.
3889 WindowState swin = wtoken.startingWindow;
3890 if (swin != null && (swin.mDrawPending
3891 || swin.mCommitDrawPending)) {
3892 swin.mPolicyVisibility = false;
3893 swin.mPolicyVisibilityAfterAnim = false;
3894 }
3895 }
Romain Guy06882f82009-06-10 13:36:04 -07003896
Joe Onorato8a9b2202010-02-26 18:56:32 -08003897 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3899 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003900
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003901 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003903 if (performLayout) {
3904 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3905 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07003906 } else {
3907 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 }
3910 }
3911
3912 if (wtoken.animation != null) {
3913 delayed = true;
3914 }
Romain Guy06882f82009-06-10 13:36:04 -07003915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003916 return delayed;
3917 }
3918
3919 public void setAppVisibility(IBinder token, boolean visible) {
3920 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3921 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003922 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 }
3924
3925 AppWindowToken wtoken;
3926
3927 synchronized(mWindowMap) {
3928 wtoken = findAppWindowToken(token);
3929 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003930 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 return;
3932 }
3933
3934 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003935 RuntimeException e = null;
3936 if (!HIDE_STACK_CRAWLS) {
3937 e = new RuntimeException();
3938 e.fillInStackTrace();
3939 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003940 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 + "): mNextAppTransition=" + mNextAppTransition
3942 + " hidden=" + wtoken.hidden
3943 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3944 }
Romain Guy06882f82009-06-10 13:36:04 -07003945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 // If we are preparing an app transition, then delay changing
3947 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003948 if (!mDisplayFrozen && mPolicy.isScreenOn()
3949 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 // Already in requested state, don't do anything more.
3951 if (wtoken.hiddenRequested != visible) {
3952 return;
3953 }
3954 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003955
Joe Onorato8a9b2202010-02-26 18:56:32 -08003956 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 TAG, "Setting dummy animation on: " + wtoken);
3958 wtoken.setDummyAnimation();
3959 mOpeningApps.remove(wtoken);
3960 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003961 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003962 wtoken.inPendingTransaction = true;
3963 if (visible) {
3964 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 wtoken.startingDisplayed = false;
3966 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003967
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003968 // If the token is currently hidden (should be the
3969 // common case), then we need to set up to wait for
3970 // its windows to be ready.
3971 if (wtoken.hidden) {
3972 wtoken.allDrawn = false;
3973 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003974
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003975 if (wtoken.clientHidden) {
3976 // In the case where we are making an app visible
3977 // but holding off for a transition, we still need
3978 // to tell the client to make its windows visible so
3979 // they get drawn. Otherwise, we will wait on
3980 // performing the transition until all windows have
3981 // been drawn, they never will be, and we are sad.
3982 wtoken.clientHidden = false;
3983 wtoken.sendAppVisibilityToClients();
3984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
3986 } else {
3987 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003988
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003989 // If the token is currently visible (should be the
3990 // common case), then set up to wait for it to be hidden.
3991 if (!wtoken.hidden) {
3992 wtoken.waitingToHide = true;
3993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003994 }
3995 return;
3996 }
Romain Guy06882f82009-06-10 13:36:04 -07003997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003999 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 wtoken.updateReportedVisibilityLocked();
4001 Binder.restoreCallingIdentity(origId);
4002 }
4003 }
4004
4005 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4006 boolean unfreezeSurfaceNow, boolean force) {
4007 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004008 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 + " force=" + force);
4010 final int N = wtoken.allAppWindows.size();
4011 boolean unfrozeWindows = false;
4012 for (int i=0; i<N; i++) {
4013 WindowState w = wtoken.allAppWindows.get(i);
4014 if (w.mAppFreezing) {
4015 w.mAppFreezing = false;
4016 if (w.mSurface != null && !w.mOrientationChanging) {
4017 w.mOrientationChanging = true;
4018 }
4019 unfrozeWindows = true;
4020 }
4021 }
4022 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 wtoken.freezingScreen = false;
4025 mAppsFreezingScreen--;
4026 }
4027 if (unfreezeSurfaceNow) {
4028 if (unfrozeWindows) {
4029 mLayoutNeeded = true;
4030 performLayoutAndPlaceSurfacesLocked();
4031 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004032 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 }
4034 }
4035 }
Romain Guy06882f82009-06-10 13:36:04 -07004036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004037 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4038 int configChanges) {
4039 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004040 RuntimeException e = null;
4041 if (!HIDE_STACK_CRAWLS) {
4042 e = new RuntimeException();
4043 e.fillInStackTrace();
4044 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004045 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 + ": hidden=" + wtoken.hidden + " freezing="
4047 + wtoken.freezingScreen, e);
4048 }
4049 if (!wtoken.hiddenRequested) {
4050 if (!wtoken.freezingScreen) {
4051 wtoken.freezingScreen = true;
4052 mAppsFreezingScreen++;
4053 if (mAppsFreezingScreen == 1) {
4054 startFreezingDisplayLocked();
4055 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4056 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4057 5000);
4058 }
4059 }
4060 final int N = wtoken.allAppWindows.size();
4061 for (int i=0; i<N; i++) {
4062 WindowState w = wtoken.allAppWindows.get(i);
4063 w.mAppFreezing = true;
4064 }
4065 }
4066 }
Romain Guy06882f82009-06-10 13:36:04 -07004067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 public void startAppFreezingScreen(IBinder token, int configChanges) {
4069 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4070 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004071 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 }
4073
4074 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004075 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004076 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 return;
4078 }
Romain Guy06882f82009-06-10 13:36:04 -07004079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 AppWindowToken wtoken = findAppWindowToken(token);
4081 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004082 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 return;
4084 }
4085 final long origId = Binder.clearCallingIdentity();
4086 startAppFreezingScreenLocked(wtoken, configChanges);
4087 Binder.restoreCallingIdentity(origId);
4088 }
4089 }
Romain Guy06882f82009-06-10 13:36:04 -07004090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 public void stopAppFreezingScreen(IBinder token, boolean force) {
4092 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4093 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004094 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 }
4096
4097 synchronized(mWindowMap) {
4098 AppWindowToken wtoken = findAppWindowToken(token);
4099 if (wtoken == null || wtoken.appToken == null) {
4100 return;
4101 }
4102 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004103 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4105 unsetAppFreezingScreenLocked(wtoken, true, force);
4106 Binder.restoreCallingIdentity(origId);
4107 }
4108 }
Romain Guy06882f82009-06-10 13:36:04 -07004109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 public void removeAppToken(IBinder token) {
4111 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4112 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004113 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 }
4115
4116 AppWindowToken wtoken = null;
4117 AppWindowToken startingToken = null;
4118 boolean delayed = false;
4119
4120 final long origId = Binder.clearCallingIdentity();
4121 synchronized(mWindowMap) {
4122 WindowToken basewtoken = mTokenMap.remove(token);
4123 mTokenList.remove(basewtoken);
4124 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004125 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004126 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 wtoken.inPendingTransaction = false;
4128 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004129 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 if (mClosingApps.contains(wtoken)) {
4131 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004132 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004134 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 delayed = true;
4136 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004137 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 TAG, "Removing app " + wtoken + " delayed=" + delayed
4139 + " animation=" + wtoken.animation
4140 + " animating=" + wtoken.animating);
4141 if (delayed) {
4142 // set the token aside because it has an active animation to be finished
4143 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004144 } else {
4145 // Make sure there is no animation running on this token,
4146 // so any windows associated with it will be removed as
4147 // soon as their animations are complete
4148 wtoken.animation = null;
4149 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 }
4151 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004152 if (mLastEnterAnimToken == wtoken) {
4153 mLastEnterAnimToken = null;
4154 mLastEnterAnimParams = null;
4155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004156 wtoken.removed = true;
4157 if (wtoken.startingData != null) {
4158 startingToken = wtoken;
4159 }
4160 unsetAppFreezingScreenLocked(wtoken, true, true);
4161 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004162 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 mFocusedApp = null;
4164 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004165 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 }
4167 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004168 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 }
Romain Guy06882f82009-06-10 13:36:04 -07004170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 if (!delayed && wtoken != null) {
4172 wtoken.updateReportedVisibilityLocked();
4173 }
4174 }
4175 Binder.restoreCallingIdentity(origId);
4176
4177 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004178 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 + startingToken + ": app token removed");
4180 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4181 mH.sendMessage(m);
4182 }
4183 }
4184
4185 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4186 final int NW = token.windows.size();
4187 for (int i=0; i<NW; i++) {
4188 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004189 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004191 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 int j = win.mChildWindows.size();
4193 while (j > 0) {
4194 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004195 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004196 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004197 "Tmp removing child window " + cwin);
4198 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 }
4200 }
4201 return NW > 0;
4202 }
4203
4204 void dumpAppTokensLocked() {
4205 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004206 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 }
4208 }
Romain Guy06882f82009-06-10 13:36:04 -07004209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 void dumpWindowsLocked() {
4211 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004212 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213 }
4214 }
Romain Guy06882f82009-06-10 13:36:04 -07004215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 private int findWindowOffsetLocked(int tokenPos) {
4217 final int NW = mWindows.size();
4218
4219 if (tokenPos >= mAppTokens.size()) {
4220 int i = NW;
4221 while (i > 0) {
4222 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004223 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 if (win.getAppToken() != null) {
4225 return i+1;
4226 }
4227 }
4228 }
4229
4230 while (tokenPos > 0) {
4231 // Find the first app token below the new position that has
4232 // a window displayed.
4233 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004234 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004235 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004236 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004237 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004238 "Skipping token -- currently sending to bottom");
4239 tokenPos--;
4240 continue;
4241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 int i = wtoken.windows.size();
4243 while (i > 0) {
4244 i--;
4245 WindowState win = wtoken.windows.get(i);
4246 int j = win.mChildWindows.size();
4247 while (j > 0) {
4248 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004249 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004250 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 for (int pos=NW-1; pos>=0; pos--) {
4252 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004253 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 "Found child win @" + (pos+1));
4255 return pos+1;
4256 }
4257 }
4258 }
4259 }
4260 for (int pos=NW-1; pos>=0; pos--) {
4261 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004262 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 return pos+1;
4264 }
4265 }
4266 }
4267 tokenPos--;
4268 }
4269
4270 return 0;
4271 }
4272
4273 private final int reAddWindowLocked(int index, WindowState win) {
4274 final int NCW = win.mChildWindows.size();
4275 boolean added = false;
4276 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004277 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004279 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004280 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 mWindows.add(index, win);
4282 index++;
4283 added = true;
4284 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004285 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004286 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 mWindows.add(index, cwin);
4288 index++;
4289 }
4290 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004291 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004292 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 mWindows.add(index, win);
4294 index++;
4295 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004296 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 return index;
4298 }
Romain Guy06882f82009-06-10 13:36:04 -07004299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4301 final int NW = token.windows.size();
4302 for (int i=0; i<NW; i++) {
4303 index = reAddWindowLocked(index, token.windows.get(i));
4304 }
4305 return index;
4306 }
4307
4308 public void moveAppToken(int index, IBinder token) {
4309 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4310 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004311 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 }
4313
4314 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004315 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 if (DEBUG_REORDER) dumpAppTokensLocked();
4317 final AppWindowToken wtoken = findAppWindowToken(token);
4318 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004319 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 + token + " (" + wtoken + ")");
4321 return;
4322 }
4323 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004324 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004328 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 if (DEBUG_REORDER) dumpWindowsLocked();
4330 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004331 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 if (DEBUG_REORDER) dumpWindowsLocked();
4333 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004334 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 if (DEBUG_REORDER) dumpWindowsLocked();
4336 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 mLayoutNeeded = true;
4338 performLayoutAndPlaceSurfacesLocked();
4339 }
4340 Binder.restoreCallingIdentity(origId);
4341 }
4342 }
4343
4344 private void removeAppTokensLocked(List<IBinder> tokens) {
4345 // XXX This should be done more efficiently!
4346 // (take advantage of the fact that both lists should be
4347 // ordered in the same way.)
4348 int N = tokens.size();
4349 for (int i=0; i<N; i++) {
4350 IBinder token = tokens.get(i);
4351 final AppWindowToken wtoken = findAppWindowToken(token);
4352 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004353 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 + token + " (" + wtoken + ")");
4355 i--;
4356 N--;
4357 }
4358 }
4359 }
4360
Dianne Hackborna8f60182009-09-01 19:01:50 -07004361 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4362 boolean updateFocusAndLayout) {
4363 // First remove all of the windows from the list.
4364 tmpRemoveAppWindowsLocked(wtoken);
4365
4366 // Where to start adding?
4367 int pos = findWindowOffsetLocked(tokenPos);
4368
4369 // And now add them back at the correct place.
4370 pos = reAddAppWindowsLocked(pos, wtoken);
4371
4372 if (updateFocusAndLayout) {
4373 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4374 assignLayersLocked();
4375 }
4376 mLayoutNeeded = true;
4377 performLayoutAndPlaceSurfacesLocked();
4378 }
4379 }
4380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4382 // First remove all of the windows from the list.
4383 final int N = tokens.size();
4384 int i;
4385 for (i=0; i<N; i++) {
4386 WindowToken token = mTokenMap.get(tokens.get(i));
4387 if (token != null) {
4388 tmpRemoveAppWindowsLocked(token);
4389 }
4390 }
4391
4392 // Where to start adding?
4393 int pos = findWindowOffsetLocked(tokenPos);
4394
4395 // And now add them back at the correct place.
4396 for (i=0; i<N; i++) {
4397 WindowToken token = mTokenMap.get(tokens.get(i));
4398 if (token != null) {
4399 pos = reAddAppWindowsLocked(pos, token);
4400 }
4401 }
4402
Dianne Hackborna8f60182009-09-01 19:01:50 -07004403 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4404 assignLayersLocked();
4405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004406 mLayoutNeeded = true;
4407 performLayoutAndPlaceSurfacesLocked();
4408
4409 //dump();
4410 }
4411
4412 public void moveAppTokensToTop(List<IBinder> tokens) {
4413 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4414 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004415 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 }
4417
4418 final long origId = Binder.clearCallingIdentity();
4419 synchronized(mWindowMap) {
4420 removeAppTokensLocked(tokens);
4421 final int N = tokens.size();
4422 for (int i=0; i<N; i++) {
4423 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4424 if (wt != null) {
4425 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004426 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004427 mToTopApps.remove(wt);
4428 mToBottomApps.remove(wt);
4429 mToTopApps.add(wt);
4430 wt.sendingToBottom = false;
4431 wt.sendingToTop = true;
4432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 }
4434 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004435
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004436 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004437 moveAppWindowsLocked(tokens, mAppTokens.size());
4438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 }
4440 Binder.restoreCallingIdentity(origId);
4441 }
4442
4443 public void moveAppTokensToBottom(List<IBinder> tokens) {
4444 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4445 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004446 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 }
4448
4449 final long origId = Binder.clearCallingIdentity();
4450 synchronized(mWindowMap) {
4451 removeAppTokensLocked(tokens);
4452 final int N = tokens.size();
4453 int pos = 0;
4454 for (int i=0; i<N; i++) {
4455 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4456 if (wt != null) {
4457 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004458 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004459 mToTopApps.remove(wt);
4460 mToBottomApps.remove(wt);
4461 mToBottomApps.add(i, wt);
4462 wt.sendingToTop = false;
4463 wt.sendingToBottom = true;
4464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 pos++;
4466 }
4467 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004468
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004469 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004470 moveAppWindowsLocked(tokens, 0);
4471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 }
4473 Binder.restoreCallingIdentity(origId);
4474 }
4475
4476 // -------------------------------------------------------------
4477 // Misc IWindowSession methods
4478 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004479
Jim Miller284b62e2010-06-08 14:27:42 -07004480 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004481 {
Jim Miller284b62e2010-06-08 14:27:42 -07004482 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4483 // called before DevicePolicyManagerService has started.
4484 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4485 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4486 Context.DEVICE_POLICY_SERVICE);
4487 if (dpm != null) {
4488 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4489 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4490 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4491 }
Jim Millerd6b57052010-06-07 17:52:42 -07004492 }
Jim Miller284b62e2010-06-08 14:27:42 -07004493 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004494 }
4495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004497 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 != PackageManager.PERMISSION_GRANTED) {
4499 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4500 }
Jim Millerd6b57052010-06-07 17:52:42 -07004501
Jim Miller284b62e2010-06-08 14:27:42 -07004502 synchronized (mKeyguardTokenWatcher) {
4503 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 }
4506
4507 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004508 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 != PackageManager.PERMISSION_GRANTED) {
4510 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512
Jim Miller284b62e2010-06-08 14:27:42 -07004513 synchronized (mKeyguardTokenWatcher) {
4514 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004515
Jim Miller284b62e2010-06-08 14:27:42 -07004516 if (!mKeyguardTokenWatcher.isAcquired()) {
4517 // If we are the last one to reenable the keyguard wait until
4518 // we have actually finished reenabling until returning.
4519 // It is possible that reenableKeyguard() can be called before
4520 // the previous disableKeyguard() is handled, in which case
4521 // neither mKeyguardTokenWatcher.acquired() or released() would
4522 // be called. In that case mKeyguardDisabled will be false here
4523 // and we have nothing to wait for.
4524 while (mKeyguardDisabled) {
4525 try {
4526 mKeyguardTokenWatcher.wait();
4527 } catch (InterruptedException e) {
4528 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 }
4530 }
4531 }
4532 }
4533 }
4534
4535 /**
4536 * @see android.app.KeyguardManager#exitKeyguardSecurely
4537 */
4538 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004539 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 != PackageManager.PERMISSION_GRANTED) {
4541 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4542 }
4543 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4544 public void onKeyguardExitResult(boolean success) {
4545 try {
4546 callback.onKeyguardExitResult(success);
4547 } catch (RemoteException e) {
4548 // Client has died, we don't care.
4549 }
4550 }
4551 });
4552 }
4553
4554 public boolean inKeyguardRestrictedInputMode() {
4555 return mPolicy.inKeyguardRestrictedKeyInputMode();
4556 }
Romain Guy06882f82009-06-10 13:36:04 -07004557
Dianne Hackbornffa42482009-09-23 22:20:11 -07004558 public void closeSystemDialogs(String reason) {
4559 synchronized(mWindowMap) {
4560 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004561 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004562 if (w.mSurface != null) {
4563 try {
4564 w.mClient.closeSystemDialogs(reason);
4565 } catch (RemoteException e) {
4566 }
4567 }
4568 }
4569 }
4570 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 static float fixScale(float scale) {
4573 if (scale < 0) scale = 0;
4574 else if (scale > 20) scale = 20;
4575 return Math.abs(scale);
4576 }
Romain Guy06882f82009-06-10 13:36:04 -07004577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 public void setAnimationScale(int which, float scale) {
4579 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4580 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004581 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 }
4583
4584 if (scale < 0) scale = 0;
4585 else if (scale > 20) scale = 20;
4586 scale = Math.abs(scale);
4587 switch (which) {
4588 case 0: mWindowAnimationScale = fixScale(scale); break;
4589 case 1: mTransitionAnimationScale = fixScale(scale); break;
4590 }
Romain Guy06882f82009-06-10 13:36:04 -07004591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 // Persist setting
4593 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4594 }
Romain Guy06882f82009-06-10 13:36:04 -07004595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 public void setAnimationScales(float[] scales) {
4597 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4598 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004599 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
4601
4602 if (scales != null) {
4603 if (scales.length >= 1) {
4604 mWindowAnimationScale = fixScale(scales[0]);
4605 }
4606 if (scales.length >= 2) {
4607 mTransitionAnimationScale = fixScale(scales[1]);
4608 }
4609 }
Romain Guy06882f82009-06-10 13:36:04 -07004610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 // Persist setting
4612 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4613 }
Romain Guy06882f82009-06-10 13:36:04 -07004614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 public float getAnimationScale(int which) {
4616 switch (which) {
4617 case 0: return mWindowAnimationScale;
4618 case 1: return mTransitionAnimationScale;
4619 }
4620 return 0;
4621 }
Romain Guy06882f82009-06-10 13:36:04 -07004622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 public float[] getAnimationScales() {
4624 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4625 }
Romain Guy06882f82009-06-10 13:36:04 -07004626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 public int getSwitchState(int sw) {
4628 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4629 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004630 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004632 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 }
Romain Guy06882f82009-06-10 13:36:04 -07004634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 public int getSwitchStateForDevice(int devid, int sw) {
4636 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4637 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004638 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004640 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 }
Romain Guy06882f82009-06-10 13:36:04 -07004642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 public int getScancodeState(int sw) {
4644 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4645 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004646 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004648 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004649 }
Romain Guy06882f82009-06-10 13:36:04 -07004650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 public int getScancodeStateForDevice(int devid, int sw) {
4652 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4653 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004654 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004656 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 }
Romain Guy06882f82009-06-10 13:36:04 -07004658
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004659 public int getTrackballScancodeState(int sw) {
4660 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4661 "getTrackballScancodeState()")) {
4662 throw new SecurityException("Requires READ_INPUT_STATE permission");
4663 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004664 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004665 }
4666
4667 public int getDPadScancodeState(int sw) {
4668 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4669 "getDPadScancodeState()")) {
4670 throw new SecurityException("Requires READ_INPUT_STATE permission");
4671 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004672 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004673 }
4674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004675 public int getKeycodeState(int sw) {
4676 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4677 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004678 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004680 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 }
Romain Guy06882f82009-06-10 13:36:04 -07004682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 public int getKeycodeStateForDevice(int devid, int sw) {
4684 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4685 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004686 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004688 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 }
Romain Guy06882f82009-06-10 13:36:04 -07004690
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004691 public int getTrackballKeycodeState(int sw) {
4692 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4693 "getTrackballKeycodeState()")) {
4694 throw new SecurityException("Requires READ_INPUT_STATE permission");
4695 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004696 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004697 }
4698
4699 public int getDPadKeycodeState(int sw) {
4700 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4701 "getDPadKeycodeState()")) {
4702 throw new SecurityException("Requires READ_INPUT_STATE permission");
4703 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004704 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004705 }
Jeff Browna41ca772010-08-11 14:46:32 -07004706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004708 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 }
Romain Guy06882f82009-06-10 13:36:04 -07004710
Jeff Browna41ca772010-08-11 14:46:32 -07004711 public InputChannel monitorInput(String inputChannelName) {
4712 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4713 "monitorInput()")) {
4714 throw new SecurityException("Requires READ_INPUT_STATE permission");
4715 }
4716 return mInputManager.monitorInput(inputChannelName);
4717 }
4718
Jeff Brown8d608662010-08-30 03:02:23 -07004719 public InputDevice getInputDevice(int deviceId) {
4720 return mInputManager.getInputDevice(deviceId);
4721 }
4722
4723 public int[] getInputDeviceIds() {
4724 return mInputManager.getInputDeviceIds();
4725 }
4726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 public void enableScreenAfterBoot() {
4728 synchronized(mWindowMap) {
4729 if (mSystemBooted) {
4730 return;
4731 }
4732 mSystemBooted = true;
4733 }
Romain Guy06882f82009-06-10 13:36:04 -07004734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 performEnableScreen();
4736 }
Romain Guy06882f82009-06-10 13:36:04 -07004737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 public void enableScreenIfNeededLocked() {
4739 if (mDisplayEnabled) {
4740 return;
4741 }
4742 if (!mSystemBooted) {
4743 return;
4744 }
4745 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4746 }
Romain Guy06882f82009-06-10 13:36:04 -07004747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 public void performEnableScreen() {
4749 synchronized(mWindowMap) {
4750 if (mDisplayEnabled) {
4751 return;
4752 }
4753 if (!mSystemBooted) {
4754 return;
4755 }
Romain Guy06882f82009-06-10 13:36:04 -07004756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004757 // Don't enable the screen until all existing windows
4758 // have been drawn.
4759 final int N = mWindows.size();
4760 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004761 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004762 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 return;
4764 }
4765 }
Romain Guy06882f82009-06-10 13:36:04 -07004766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 mDisplayEnabled = true;
4768 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 StringWriter sw = new StringWriter();
4771 PrintWriter pw = new PrintWriter(sw);
4772 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004773 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 }
4775 try {
4776 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4777 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004778 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004779 Parcel data = Parcel.obtain();
4780 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4781 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4782 data, null, 0);
4783 data.recycle();
4784 }
4785 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004786 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 }
4788 }
Romain Guy06882f82009-06-10 13:36:04 -07004789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004793 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4794 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 }
Romain Guy06882f82009-06-10 13:36:04 -07004796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797 public void setInTouchMode(boolean mode) {
4798 synchronized(mWindowMap) {
4799 mInTouchMode = mode;
4800 }
4801 }
4802
Romain Guy06882f82009-06-10 13:36:04 -07004803 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004804 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004806 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004807 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 }
4809
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004810 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004811 }
Romain Guy06882f82009-06-10 13:36:04 -07004812
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004813 public void setRotationUnchecked(int rotation,
4814 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004815 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004816 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004818 long origId = Binder.clearCallingIdentity();
4819 boolean changed;
4820 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004821 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 }
Romain Guy06882f82009-06-10 13:36:04 -07004823
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004824 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004825 sendNewConfiguration();
4826 }
Romain Guy06882f82009-06-10 13:36:04 -07004827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004828 Binder.restoreCallingIdentity(origId);
4829 }
Romain Guy06882f82009-06-10 13:36:04 -07004830
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004831 /**
4832 * Apply a new rotation to the screen, respecting the requests of
4833 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4834 * re-evaluate the desired rotation.
4835 *
4836 * Returns null if the rotation has been changed. In this case YOU
4837 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4838 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004839 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 boolean changed;
4841 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4842 rotation = mRequestedRotation;
4843 } else {
4844 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004845 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004847 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004848 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004850 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004853 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004854 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 "Rotation changed to " + rotation
4856 + " from " + mRotation
4857 + " (forceApp=" + mForcedAppOrientation
4858 + ", req=" + mRequestedRotation + ")");
4859 mRotation = rotation;
4860 mWindowsFreezingScreen = true;
4861 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4862 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4863 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004864 mWaitingForConfig = true;
4865 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004867 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004868 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07004870 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 }
4872 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004873 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 if (w.mSurface != null) {
4875 w.mOrientationChanging = true;
4876 }
4877 }
4878 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4879 try {
4880 mRotationWatchers.get(i).onRotationChanged(rotation);
4881 } catch (RemoteException e) {
4882 }
4883 }
4884 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 return changed;
4887 }
Romain Guy06882f82009-06-10 13:36:04 -07004888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 public int getRotation() {
4890 return mRotation;
4891 }
4892
4893 public int watchRotation(IRotationWatcher watcher) {
4894 final IBinder watcherBinder = watcher.asBinder();
4895 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4896 public void binderDied() {
4897 synchronized (mWindowMap) {
4898 for (int i=0; i<mRotationWatchers.size(); i++) {
4899 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004900 IRotationWatcher removed = mRotationWatchers.remove(i);
4901 if (removed != null) {
4902 removed.asBinder().unlinkToDeath(this, 0);
4903 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004904 i--;
4905 }
4906 }
4907 }
4908 }
4909 };
Romain Guy06882f82009-06-10 13:36:04 -07004910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004911 synchronized (mWindowMap) {
4912 try {
4913 watcher.asBinder().linkToDeath(dr, 0);
4914 mRotationWatchers.add(watcher);
4915 } catch (RemoteException e) {
4916 // Client died, no cleanup needed.
4917 }
Romain Guy06882f82009-06-10 13:36:04 -07004918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 return mRotation;
4920 }
4921 }
4922
4923 /**
4924 * Starts the view server on the specified port.
4925 *
4926 * @param port The port to listener to.
4927 *
4928 * @return True if the server was successfully started, false otherwise.
4929 *
4930 * @see com.android.server.ViewServer
4931 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
4932 */
4933 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07004934 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 return false;
4936 }
4937
4938 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4939 return false;
4940 }
4941
4942 if (port < 1024) {
4943 return false;
4944 }
4945
4946 if (mViewServer != null) {
4947 if (!mViewServer.isRunning()) {
4948 try {
4949 return mViewServer.start();
4950 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004951 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 }
4953 }
4954 return false;
4955 }
4956
4957 try {
4958 mViewServer = new ViewServer(this, port);
4959 return mViewServer.start();
4960 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004961 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 }
4963 return false;
4964 }
4965
Romain Guy06882f82009-06-10 13:36:04 -07004966 private boolean isSystemSecure() {
4967 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4968 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4969 }
4970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 /**
4972 * Stops the view server if it exists.
4973 *
4974 * @return True if the server stopped, false if it wasn't started or
4975 * couldn't be stopped.
4976 *
4977 * @see com.android.server.ViewServer
4978 */
4979 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07004980 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004981 return false;
4982 }
4983
4984 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4985 return false;
4986 }
4987
4988 if (mViewServer != null) {
4989 return mViewServer.stop();
4990 }
4991 return false;
4992 }
4993
4994 /**
4995 * Indicates whether the view server is running.
4996 *
4997 * @return True if the server is running, false otherwise.
4998 *
4999 * @see com.android.server.ViewServer
5000 */
5001 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005002 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005003 return false;
5004 }
5005
5006 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5007 return false;
5008 }
5009
5010 return mViewServer != null && mViewServer.isRunning();
5011 }
5012
5013 /**
5014 * Lists all availble windows in the system. The listing is written in the
5015 * specified Socket's output stream with the following syntax:
5016 * windowHashCodeInHexadecimal windowName
5017 * Each line of the ouput represents a different window.
5018 *
5019 * @param client The remote client to send the listing to.
5020 * @return False if an error occured, true otherwise.
5021 */
5022 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005023 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 return false;
5025 }
5026
5027 boolean result = true;
5028
Jeff Browne33348b2010-07-15 23:54:05 -07005029 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005030 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005032 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 }
5034
5035 BufferedWriter out = null;
5036
5037 // Any uncaught exception will crash the system process
5038 try {
5039 OutputStream clientStream = client.getOutputStream();
5040 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5041
5042 final int count = windows.length;
5043 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005044 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 out.write(Integer.toHexString(System.identityHashCode(w)));
5046 out.write(' ');
5047 out.append(w.mAttrs.getTitle());
5048 out.write('\n');
5049 }
5050
5051 out.write("DONE.\n");
5052 out.flush();
5053 } catch (Exception e) {
5054 result = false;
5055 } finally {
5056 if (out != null) {
5057 try {
5058 out.close();
5059 } catch (IOException e) {
5060 result = false;
5061 }
5062 }
5063 }
5064
5065 return result;
5066 }
5067
5068 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005069 * Returns the focused window in the following format:
5070 * windowHashCodeInHexadecimal windowName
5071 *
5072 * @param client The remote client to send the listing to.
5073 * @return False if an error occurred, true otherwise.
5074 */
5075 boolean viewServerGetFocusedWindow(Socket client) {
5076 if (isSystemSecure()) {
5077 return false;
5078 }
5079
5080 boolean result = true;
5081
5082 WindowState focusedWindow = getFocusedWindow();
5083
5084 BufferedWriter out = null;
5085
5086 // Any uncaught exception will crash the system process
5087 try {
5088 OutputStream clientStream = client.getOutputStream();
5089 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5090
5091 if(focusedWindow != null) {
5092 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5093 out.write(' ');
5094 out.append(focusedWindow.mAttrs.getTitle());
5095 }
5096 out.write('\n');
5097 out.flush();
5098 } catch (Exception e) {
5099 result = false;
5100 } finally {
5101 if (out != null) {
5102 try {
5103 out.close();
5104 } catch (IOException e) {
5105 result = false;
5106 }
5107 }
5108 }
5109
5110 return result;
5111 }
5112
5113 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 * Sends a command to a target window. The result of the command, if any, will be
5115 * written in the output stream of the specified socket.
5116 *
5117 * The parameters must follow this syntax:
5118 * windowHashcode extra
5119 *
5120 * Where XX is the length in characeters of the windowTitle.
5121 *
5122 * The first parameter is the target window. The window with the specified hashcode
5123 * will be the target. If no target can be found, nothing happens. The extra parameters
5124 * will be delivered to the target window and as parameters to the command itself.
5125 *
5126 * @param client The remote client to sent the result, if any, to.
5127 * @param command The command to execute.
5128 * @param parameters The command parameters.
5129 *
5130 * @return True if the command was successfully delivered, false otherwise. This does
5131 * not indicate whether the command itself was successful.
5132 */
5133 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005134 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005135 return false;
5136 }
5137
5138 boolean success = true;
5139 Parcel data = null;
5140 Parcel reply = null;
5141
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005142 BufferedWriter out = null;
5143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005144 // Any uncaught exception will crash the system process
5145 try {
5146 // Find the hashcode of the window
5147 int index = parameters.indexOf(' ');
5148 if (index == -1) {
5149 index = parameters.length();
5150 }
5151 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005152 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153
5154 // Extract the command's parameter after the window description
5155 if (index < parameters.length()) {
5156 parameters = parameters.substring(index + 1);
5157 } else {
5158 parameters = "";
5159 }
5160
5161 final WindowManagerService.WindowState window = findWindow(hashCode);
5162 if (window == null) {
5163 return false;
5164 }
5165
5166 data = Parcel.obtain();
5167 data.writeInterfaceToken("android.view.IWindow");
5168 data.writeString(command);
5169 data.writeString(parameters);
5170 data.writeInt(1);
5171 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5172
5173 reply = Parcel.obtain();
5174
5175 final IBinder binder = window.mClient.asBinder();
5176 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5177 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5178
5179 reply.readException();
5180
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005181 if (!client.isOutputShutdown()) {
5182 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5183 out.write("DONE\n");
5184 out.flush();
5185 }
5186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005187 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005188 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005189 success = false;
5190 } finally {
5191 if (data != null) {
5192 data.recycle();
5193 }
5194 if (reply != null) {
5195 reply.recycle();
5196 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005197 if (out != null) {
5198 try {
5199 out.close();
5200 } catch (IOException e) {
5201
5202 }
5203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 }
5205
5206 return success;
5207 }
5208
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005209 public void addWindowChangeListener(WindowChangeListener listener) {
5210 synchronized(mWindowMap) {
5211 mWindowChangeListeners.add(listener);
5212 }
5213 }
5214
5215 public void removeWindowChangeListener(WindowChangeListener listener) {
5216 synchronized(mWindowMap) {
5217 mWindowChangeListeners.remove(listener);
5218 }
5219 }
5220
5221 private void notifyWindowsChanged() {
5222 WindowChangeListener[] windowChangeListeners;
5223 synchronized(mWindowMap) {
5224 if(mWindowChangeListeners.isEmpty()) {
5225 return;
5226 }
5227 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5228 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5229 }
5230 int N = windowChangeListeners.length;
5231 for(int i = 0; i < N; i++) {
5232 windowChangeListeners[i].windowsChanged();
5233 }
5234 }
5235
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005236 private void notifyFocusChanged() {
5237 WindowChangeListener[] windowChangeListeners;
5238 synchronized(mWindowMap) {
5239 if(mWindowChangeListeners.isEmpty()) {
5240 return;
5241 }
5242 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5243 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5244 }
5245 int N = windowChangeListeners.length;
5246 for(int i = 0; i < N; i++) {
5247 windowChangeListeners[i].focusChanged();
5248 }
5249 }
5250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 private WindowState findWindow(int hashCode) {
5252 if (hashCode == -1) {
5253 return getFocusedWindow();
5254 }
5255
5256 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005257 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005258 final int count = windows.size();
5259
5260 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005261 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 if (System.identityHashCode(w) == hashCode) {
5263 return w;
5264 }
5265 }
5266 }
5267
5268 return null;
5269 }
5270
5271 /*
5272 * Instruct the Activity Manager to fetch the current configuration and broadcast
5273 * that to config-changed listeners if appropriate.
5274 */
5275 void sendNewConfiguration() {
5276 try {
5277 mActivityManager.updateConfiguration(null);
5278 } catch (RemoteException e) {
5279 }
5280 }
Romain Guy06882f82009-06-10 13:36:04 -07005281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 public Configuration computeNewConfiguration() {
5283 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005284 return computeNewConfigurationLocked();
5285 }
5286 }
Romain Guy06882f82009-06-10 13:36:04 -07005287
Dianne Hackbornc485a602009-03-24 22:39:49 -07005288 Configuration computeNewConfigurationLocked() {
5289 Configuration config = new Configuration();
5290 if (!computeNewConfigurationLocked(config)) {
5291 return null;
5292 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005293 return config;
5294 }
Romain Guy06882f82009-06-10 13:36:04 -07005295
Dianne Hackbornc485a602009-03-24 22:39:49 -07005296 boolean computeNewConfigurationLocked(Configuration config) {
5297 if (mDisplay == null) {
5298 return false;
5299 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005300
5301 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005302
5303 // Use the effective "visual" dimensions based on current rotation
5304 final boolean rotated = (mRotation == Surface.ROTATION_90
5305 || mRotation == Surface.ROTATION_270);
5306 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5307 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5308
Dianne Hackbornc485a602009-03-24 22:39:49 -07005309 int orientation = Configuration.ORIENTATION_SQUARE;
5310 if (dw < dh) {
5311 orientation = Configuration.ORIENTATION_PORTRAIT;
5312 } else if (dw > dh) {
5313 orientation = Configuration.ORIENTATION_LANDSCAPE;
5314 }
5315 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005316
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005317 DisplayMetrics dm = new DisplayMetrics();
5318 mDisplay.getMetrics(dm);
5319 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5320
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005321 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005322 // Note we only do this once because at this point we don't
5323 // expect the screen to change in this way at runtime, and want
5324 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005325 int longSize = dw;
5326 int shortSize = dh;
5327 if (longSize < shortSize) {
5328 int tmp = longSize;
5329 longSize = shortSize;
5330 shortSize = tmp;
5331 }
5332 longSize = (int)(longSize/dm.density);
5333 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005334
Dianne Hackborn723738c2009-06-25 19:48:04 -07005335 // These semi-magic numbers define our compatibility modes for
5336 // applications with different screens. Don't change unless you
5337 // make sure to test lots and lots of apps!
5338 if (longSize < 470) {
5339 // This is shorter than an HVGA normal density screen (which
5340 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005341 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5342 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005343 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005344 // What size is this screen screen?
5345 if (longSize >= 800 && shortSize >= 600) {
5346 // SVGA or larger screens at medium density are the point
5347 // at which we consider it to be an extra large screen.
5348 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5349 } else if (longSize >= 640 && shortSize >= 480) {
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005350 // VGA or larger screens at medium density are the point
5351 // at which we consider it to be a large screen.
5352 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5353 } else {
5354 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005355
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005356 // If this screen is wider than normal HVGA, or taller
5357 // than FWVGA, then for old apps we want to run in size
5358 // compatibility mode.
5359 if (shortSize > 321 || longSize > 570) {
5360 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5361 }
5362 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005363
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005364 // Is this a long screen?
5365 if (((longSize*3)/5) >= (shortSize-1)) {
5366 // Anything wider than WVGA (5:3) is considering to be long.
5367 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5368 } else {
5369 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5370 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005371 }
5372 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005373 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005374
Dianne Hackbornc485a602009-03-24 22:39:49 -07005375 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5376 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5377 mPolicy.adjustConfigurationLw(config);
5378 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005379 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005380
5381 // -------------------------------------------------------------
5382 // Drag and drop
5383 // -------------------------------------------------------------
5384
5385 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
5386 boolean localOnly, int width, int height, Surface outSurface) {
5387 if (DEBUG_DRAG) {
5388 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
5389 + " local=" + localOnly + " win=" + window
5390 + " asbinder=" + window.asBinder());
5391 }
5392
5393 final int callerPid = Binder.getCallingPid();
5394 final long origId = Binder.clearCallingIdentity();
5395 IBinder token = null;
5396
5397 try {
5398 synchronized (mWindowMap) {
5399 try {
5400 // !!! TODO: fail if the given window does not currently have touch focus?
5401
5402 if (mDragState == null) {
5403 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5404 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5405 outSurface.copyFrom(surface);
5406 token = new Binder();
5407 mDragState = new DragState(token, surface, localOnly);
5408 mDragState.mSurface = surface;
5409 mDragState.mLocalOnly = localOnly;
5410 token = mDragState.mToken = new Binder();
5411
5412 // 5 second timeout for this window to actually begin the drag
5413 mH.removeMessages(H.DRAG_START_TIMEOUT, window);
5414 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, window.asBinder());
5415 mH.sendMessageDelayed(msg, 5000);
5416 } else {
5417 Slog.w(TAG, "Drag already in progress");
5418 }
5419 } catch (Surface.OutOfResourcesException e) {
5420 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5421 if (mDragState != null) {
5422 mDragState.reset();
5423 mDragState = null;
5424 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005425 }
5426 }
5427 } finally {
5428 Binder.restoreCallingIdentity(origId);
5429 }
5430
5431 return token;
5432 }
5433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 // -------------------------------------------------------------
5435 // Input Events and Focus Management
5436 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005437
Jeff Brown349703e2010-06-22 01:27:15 -07005438 InputMonitor mInputMonitor = new InputMonitor();
5439
5440 /* Tracks the progress of input dispatch and ensures that input dispatch state
5441 * is kept in sync with changes in window focus, visibility, registration, and
5442 * other relevant Window Manager state transitions. */
5443 final class InputMonitor {
5444 // Current window with input focus for keys and other non-touch events. May be null.
5445 private WindowState mInputFocus;
5446
5447 // When true, prevents input dispatch from proceeding until set to false again.
5448 private boolean mInputDispatchFrozen;
5449
5450 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5451 private boolean mInputDispatchEnabled = true;
5452
5453 // Temporary list of windows information to provide to the input dispatcher.
5454 private InputWindowList mTempInputWindows = new InputWindowList();
5455
5456 // Temporary input application object to provide to the input dispatcher.
5457 private InputApplication mTempInputApplication = new InputApplication();
5458
5459 /* Notifies the window manager about a broken input channel.
5460 *
5461 * Called by the InputManager.
5462 */
5463 public void notifyInputChannelBroken(InputChannel inputChannel) {
5464 synchronized (mWindowMap) {
5465 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5466 if (windowState == null) {
5467 return; // irrelevant
5468 }
5469
5470 Slog.i(TAG, "WINDOW DIED " + windowState);
5471 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005472 }
5473 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005474
Jeff Brown519e0242010-09-15 15:18:56 -07005475 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005476 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005477 *
5478 * Called by the InputManager.
5479 */
Jeff Brown519e0242010-09-15 15:18:56 -07005480 public long notifyANR(Object token, InputChannel inputChannel) {
5481 AppWindowToken appWindowToken = null;
5482 if (inputChannel != null) {
5483 synchronized (mWindowMap) {
5484 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5485 if (windowState != null) {
5486 Slog.i(TAG, "Input event dispatching timed out sending to "
5487 + windowState.mAttrs.getTitle());
5488 appWindowToken = windowState.mAppToken;
5489 }
Jeff Brown349703e2010-06-22 01:27:15 -07005490 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005491 }
5492
Jeff Brown519e0242010-09-15 15:18:56 -07005493 if (appWindowToken == null && token != null) {
5494 appWindowToken = (AppWindowToken) token;
5495 Slog.i(TAG, "Input event dispatching timed out sending to application "
5496 + appWindowToken.stringName);
5497 }
Jeff Brown349703e2010-06-22 01:27:15 -07005498
Jeff Brown519e0242010-09-15 15:18:56 -07005499 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005500 try {
5501 // Notify the activity manager about the timeout and let it decide whether
5502 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005503 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005504 if (! abort) {
5505 // The activity manager declined to abort dispatching.
5506 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005507 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005508 }
Jeff Brown349703e2010-06-22 01:27:15 -07005509 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005510 }
5511 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005512 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005513 }
5514
Jeff Brown349703e2010-06-22 01:27:15 -07005515 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5516 synchronized (mWindowMap) {
5517 return getWindowStateForInputChannelLocked(inputChannel);
5518 }
5519 }
5520
5521 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5522 int windowCount = mWindows.size();
5523 for (int i = 0; i < windowCount; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005524 WindowState windowState = mWindows.get(i);
Jeff Brown349703e2010-06-22 01:27:15 -07005525 if (windowState.mInputChannel == inputChannel) {
5526 return windowState;
5527 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005528 }
5529
Jeff Brown349703e2010-06-22 01:27:15 -07005530 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005531 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005532
5533 private void addDragInputWindow(InputWindowList windowList) {
5534 final InputWindow inputWindow = windowList.add();
5535 inputWindow.inputChannel = mDragState.mServerChannel;
5536 inputWindow.name = "drag";
5537 inputWindow.layoutParamsFlags = 0;
5538 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5539 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5540 inputWindow.visible = true;
5541 inputWindow.canReceiveKeys = false;
5542 inputWindow.hasFocus = true;
5543 inputWindow.hasWallpaper = false;
5544 inputWindow.paused = false;
5545 inputWindow.layer = mPolicy.windowTypeToLayerLw(inputWindow.layoutParamsType)
5546 * TYPE_LAYER_MULTIPLIER
5547 + TYPE_LAYER_OFFSET;
5548 inputWindow.ownerPid = Process.myPid();
5549 inputWindow.ownerUid = Process.myUid();
5550
5551 // The drag window covers the entire display
5552 inputWindow.frameLeft = 0;
5553 inputWindow.frameTop = 0;
5554 inputWindow.frameRight = mDisplay.getWidth();
5555 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005556
Christopher Tatea53146c2010-09-07 11:57:52 -07005557 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5558 inputWindow.visibleFrameTop = inputWindow.frameTop;
5559 inputWindow.visibleFrameRight = inputWindow.frameRight;
5560 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5561
5562 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5563 inputWindow.touchableAreaTop = inputWindow.frameTop;
5564 inputWindow.touchableAreaRight = inputWindow.frameRight;
5565 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5566 }
5567
Jeff Brown349703e2010-06-22 01:27:15 -07005568 /* Updates the cached window information provided to the input dispatcher. */
5569 public void updateInputWindowsLw() {
5570 // Populate the input window list with information about all of the windows that
5571 // could potentially receive input.
5572 // As an optimization, we could try to prune the list of windows but this turns
5573 // out to be difficult because only the native code knows for sure which window
5574 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005575 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005576
5577 // If there's a drag in flight, provide a pseudowindow to catch drag input
5578 final boolean inDrag = (mDragState != null);
5579 if (inDrag) {
5580 if (DEBUG_DRAG) {
5581 Log.d(TAG, "Inserting drag window");
5582 }
5583 addDragInputWindow(mTempInputWindows);
5584 }
5585
Jeff Brown7fbdc842010-06-17 20:52:56 -07005586 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005587 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005588 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005589 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005590 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005591 continue;
5592 }
5593
Jeff Brown349703e2010-06-22 01:27:15 -07005594 final int flags = child.mAttrs.flags;
5595 final int type = child.mAttrs.type;
5596
5597 final boolean hasFocus = (child == mInputFocus);
5598 final boolean isVisible = child.isVisibleLw();
5599 final boolean hasWallpaper = (child == mWallpaperTarget)
5600 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005601
5602 // If there's a drag in progress and 'child' is a potential drop target,
5603 // make sure it's been told about the drag
5604 if (inDrag && isVisible) {
5605 mDragState.sendDragStartedIfNeededLw(child);
5606 }
5607
Jeff Brown349703e2010-06-22 01:27:15 -07005608 // Add a window to our list of input windows.
5609 final InputWindow inputWindow = mTempInputWindows.add();
5610 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005611 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005612 inputWindow.layoutParamsFlags = flags;
5613 inputWindow.layoutParamsType = type;
5614 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5615 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005616 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005617 inputWindow.hasFocus = hasFocus;
5618 inputWindow.hasWallpaper = hasWallpaper;
5619 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005620 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005621 inputWindow.ownerPid = child.mSession.mPid;
5622 inputWindow.ownerUid = child.mSession.mUid;
5623
5624 final Rect frame = child.mFrame;
5625 inputWindow.frameLeft = frame.left;
5626 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005627 inputWindow.frameRight = frame.right;
5628 inputWindow.frameBottom = frame.bottom;
5629
5630 final Rect visibleFrame = child.mVisibleFrame;
5631 inputWindow.visibleFrameLeft = visibleFrame.left;
5632 inputWindow.visibleFrameTop = visibleFrame.top;
5633 inputWindow.visibleFrameRight = visibleFrame.right;
5634 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005635
5636 switch (child.mTouchableInsets) {
5637 default:
5638 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5639 inputWindow.touchableAreaLeft = frame.left;
5640 inputWindow.touchableAreaTop = frame.top;
5641 inputWindow.touchableAreaRight = frame.right;
5642 inputWindow.touchableAreaBottom = frame.bottom;
5643 break;
5644
5645 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5646 Rect inset = child.mGivenContentInsets;
5647 inputWindow.touchableAreaLeft = frame.left + inset.left;
5648 inputWindow.touchableAreaTop = frame.top + inset.top;
5649 inputWindow.touchableAreaRight = frame.right - inset.right;
5650 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5651 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005652 }
Jeff Brown349703e2010-06-22 01:27:15 -07005653
5654 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5655 Rect inset = child.mGivenVisibleInsets;
5656 inputWindow.touchableAreaLeft = frame.left + inset.left;
5657 inputWindow.touchableAreaTop = frame.top + inset.top;
5658 inputWindow.touchableAreaRight = frame.right - inset.right;
5659 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005660 break;
5661 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005662 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005663 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005664
Jeff Brown349703e2010-06-22 01:27:15 -07005665 // Send windows to native code.
5666 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005667
Jeff Brown349703e2010-06-22 01:27:15 -07005668 // Clear the list in preparation for the next round.
5669 // Also avoids keeping InputChannel objects referenced unnecessarily.
5670 mTempInputWindows.clear();
5671 }
5672
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005673 /* Notifies that the lid switch changed state. */
5674 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5675 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5676 }
5677
Jeff Brown349703e2010-06-22 01:27:15 -07005678 /* Provides an opportunity for the window manager policy to intercept early key
5679 * processing as soon as the key has been read from the device. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005680 public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
5681 int policyFlags, boolean isScreenOn) {
5682 return mPolicy.interceptKeyBeforeQueueing(whenNanos,
5683 keyCode, down, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005684 }
5685
5686 /* Provides an opportunity for the window manager policy to process a key before
5687 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005688 public boolean interceptKeyBeforeDispatching(InputChannel focus,
5689 int action, int flags, int keyCode, int metaState, int repeatCount,
5690 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005691 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005692 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
5693 keyCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005694 }
5695
5696 /* Called when the current input focus changes.
5697 * Layer assignment is assumed to be complete by the time this is called.
5698 */
5699 public void setInputFocusLw(WindowState newWindow) {
5700 if (DEBUG_INPUT) {
5701 Slog.d(TAG, "Input focus has changed to " + newWindow);
5702 }
5703
5704 if (newWindow != mInputFocus) {
5705 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005706 // Displaying a window implicitly causes dispatching to be unpaused.
5707 // This is to protect against bugs if someone pauses dispatching but
5708 // forgets to resume.
5709 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005710 }
Jeff Brown349703e2010-06-22 01:27:15 -07005711
5712 mInputFocus = newWindow;
5713 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005714 }
5715 }
5716
Jeff Brown349703e2010-06-22 01:27:15 -07005717 public void setFocusedAppLw(AppWindowToken newApp) {
5718 // Focused app has changed.
5719 if (newApp == null) {
5720 mInputManager.setFocusedApplication(null);
5721 } else {
5722 mTempInputApplication.name = newApp.toString();
5723 mTempInputApplication.dispatchingTimeoutNanos =
5724 newApp.inputDispatchingTimeoutNanos;
5725 mTempInputApplication.token = newApp;
5726
5727 mInputManager.setFocusedApplication(mTempInputApplication);
5728 }
5729 }
5730
Jeff Brown349703e2010-06-22 01:27:15 -07005731 public void pauseDispatchingLw(WindowToken window) {
5732 if (! window.paused) {
5733 if (DEBUG_INPUT) {
5734 Slog.v(TAG, "Pausing WindowToken " + window);
5735 }
5736
5737 window.paused = true;
5738 updateInputWindowsLw();
5739 }
5740 }
5741
5742 public void resumeDispatchingLw(WindowToken window) {
5743 if (window.paused) {
5744 if (DEBUG_INPUT) {
5745 Slog.v(TAG, "Resuming WindowToken " + window);
5746 }
5747
5748 window.paused = false;
5749 updateInputWindowsLw();
5750 }
5751 }
5752
5753 public void freezeInputDispatchingLw() {
5754 if (! mInputDispatchFrozen) {
5755 if (DEBUG_INPUT) {
5756 Slog.v(TAG, "Freezing input dispatching");
5757 }
5758
5759 mInputDispatchFrozen = true;
5760 updateInputDispatchModeLw();
5761 }
5762 }
5763
5764 public void thawInputDispatchingLw() {
5765 if (mInputDispatchFrozen) {
5766 if (DEBUG_INPUT) {
5767 Slog.v(TAG, "Thawing input dispatching");
5768 }
5769
5770 mInputDispatchFrozen = false;
5771 updateInputDispatchModeLw();
5772 }
5773 }
5774
5775 public void setEventDispatchingLw(boolean enabled) {
5776 if (mInputDispatchEnabled != enabled) {
5777 if (DEBUG_INPUT) {
5778 Slog.v(TAG, "Setting event dispatching to " + enabled);
5779 }
5780
5781 mInputDispatchEnabled = enabled;
5782 updateInputDispatchModeLw();
5783 }
5784 }
5785
5786 private void updateInputDispatchModeLw() {
5787 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5788 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 public void pauseKeyDispatching(IBinder _token) {
5792 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5793 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005794 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795 }
5796
5797 synchronized (mWindowMap) {
5798 WindowToken token = mTokenMap.get(_token);
5799 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005800 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005801 }
5802 }
5803 }
5804
5805 public void resumeKeyDispatching(IBinder _token) {
5806 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5807 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005808 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 }
5810
5811 synchronized (mWindowMap) {
5812 WindowToken token = mTokenMap.get(_token);
5813 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005814 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 }
5816 }
5817 }
5818
5819 public void setEventDispatching(boolean enabled) {
5820 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5821 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005822 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005823 }
5824
5825 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005826 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 }
5828 }
Romain Guy06882f82009-06-10 13:36:04 -07005829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 /**
5831 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005832 * Even when sync is false, this method may block while waiting for current
5833 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005834 *
5835 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005836 * {@link SystemClock#uptimeMillis()} as the timebase.)
5837 * @param sync If true, wait for the event to be completed before returning to the caller.
5838 * @return Returns true if event was dispatched, false if it was dropped for any reason
5839 */
5840 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5841 long downTime = ev.getDownTime();
5842 long eventTime = ev.getEventTime();
5843
5844 int action = ev.getAction();
5845 int code = ev.getKeyCode();
5846 int repeatCount = ev.getRepeatCount();
5847 int metaState = ev.getMetaState();
5848 int deviceId = ev.getDeviceId();
5849 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005850 int source = ev.getSource();
5851
5852 if (source == InputDevice.SOURCE_UNKNOWN) {
5853 source = InputDevice.SOURCE_KEYBOARD;
5854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005855
5856 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5857 if (downTime == 0) downTime = eventTime;
5858
5859 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jeff Brownc5ed5912010-07-14 18:48:53 -07005860 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005861
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005862 final int pid = Binder.getCallingPid();
5863 final int uid = Binder.getCallingUid();
5864 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005865
Jeff Brownbbda99d2010-07-28 15:48:59 -07005866 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5867 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5868 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5869 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005870
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005871 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005872 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005873 }
5874
5875 /**
5876 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005877 * Even when sync is false, this method may block while waiting for current
5878 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005879 *
5880 * @param ev A motion event describing the pointer (touch) action. (As noted in
5881 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 * {@link SystemClock#uptimeMillis()} as the timebase.)
5883 * @param sync If true, wait for the event to be completed before returning to the caller.
5884 * @return Returns true if event was dispatched, false if it was dropped for any reason
5885 */
5886 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005887 final int pid = Binder.getCallingPid();
5888 final int uid = Binder.getCallingUid();
5889 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005890
Jeff Brownc5ed5912010-07-14 18:48:53 -07005891 MotionEvent newEvent = MotionEvent.obtain(ev);
5892 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5893 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5894 }
5895
Jeff Brownbbda99d2010-07-28 15:48:59 -07005896 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5897 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5898 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5899 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005900
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005901 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005902 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 }
Romain Guy06882f82009-06-10 13:36:04 -07005904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 /**
5906 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005907 * Even when sync is false, this method may block while waiting for current
5908 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005909 *
5910 * @param ev A motion event describing the trackball action. (As noted in
5911 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 * {@link SystemClock#uptimeMillis()} as the timebase.)
5913 * @param sync If true, wait for the event to be completed before returning to the caller.
5914 * @return Returns true if event was dispatched, false if it was dropped for any reason
5915 */
5916 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005917 final int pid = Binder.getCallingPid();
5918 final int uid = Binder.getCallingUid();
5919 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005920
Jeff Brownc5ed5912010-07-14 18:48:53 -07005921 MotionEvent newEvent = MotionEvent.obtain(ev);
5922 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5923 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5924 }
5925
Jeff Brownbbda99d2010-07-28 15:48:59 -07005926 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5927 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5928 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5929 INJECTION_TIMEOUT_MILLIS);
5930
5931 Binder.restoreCallingIdentity(ident);
5932 return reportInjectionResult(result);
5933 }
5934
5935 /**
5936 * Inject an input event into the UI without waiting for dispatch to commence.
5937 * This variant is useful for fire-and-forget input event injection. It does not
5938 * block any longer than it takes to enqueue the input event.
5939 *
5940 * @param ev An input event. (Be sure to set the input source correctly.)
5941 * @return Returns true if event was dispatched, false if it was dropped for any reason
5942 */
5943 public boolean injectInputEventNoWait(InputEvent ev) {
5944 final int pid = Binder.getCallingPid();
5945 final int uid = Binder.getCallingUid();
5946 final long ident = Binder.clearCallingIdentity();
5947
5948 final int result = mInputManager.injectInputEvent(ev, pid, uid,
5949 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
5950 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005951
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005952 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005953 return reportInjectionResult(result);
5954 }
5955
5956 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005957 switch (result) {
5958 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5959 Slog.w(TAG, "Input event injection permission denied.");
5960 throw new SecurityException(
5961 "Injecting to another application requires INJECT_EVENTS permission");
5962 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07005963 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005964 return true;
5965 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5966 Slog.w(TAG, "Input event injection timed out.");
5967 return false;
5968 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5969 default:
5970 Slog.w(TAG, "Input event injection failed.");
5971 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 }
Romain Guy06882f82009-06-10 13:36:04 -07005974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 private WindowState getFocusedWindow() {
5976 synchronized (mWindowMap) {
5977 return getFocusedWindowLocked();
5978 }
5979 }
5980
5981 private WindowState getFocusedWindowLocked() {
5982 return mCurrentFocus;
5983 }
Romain Guy06882f82009-06-10 13:36:04 -07005984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 public boolean detectSafeMode() {
5986 mSafeMode = mPolicy.detectSafeMode();
5987 return mSafeMode;
5988 }
Romain Guy06882f82009-06-10 13:36:04 -07005989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005990 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07005991 synchronized(mWindowMap) {
5992 if (mDisplay != null) {
5993 throw new IllegalStateException("Display already initialized");
5994 }
5995 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
5996 mDisplay = wm.getDefaultDisplay();
5997 mInitialDisplayWidth = mDisplay.getWidth();
5998 mInitialDisplayHeight = mDisplay.getHeight();
5999 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
6000 }
6001
6002 try {
6003 mActivityManager.updateConfiguration(null);
6004 } catch (RemoteException e) {
6005 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006006
6007 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006008 }
6009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006010 // -------------------------------------------------------------
6011 // Client Session State
6012 // -------------------------------------------------------------
6013
6014 private final class Session extends IWindowSession.Stub
6015 implements IBinder.DeathRecipient {
6016 final IInputMethodClient mClient;
6017 final IInputContext mInputContext;
6018 final int mUid;
6019 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006020 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006021 SurfaceSession mSurfaceSession;
6022 int mNumWindow = 0;
6023 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 public Session(IInputMethodClient client, IInputContext inputContext) {
6026 mClient = client;
6027 mInputContext = inputContext;
6028 mUid = Binder.getCallingUid();
6029 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006030 StringBuilder sb = new StringBuilder();
6031 sb.append("Session{");
6032 sb.append(Integer.toHexString(System.identityHashCode(this)));
6033 sb.append(" uid ");
6034 sb.append(mUid);
6035 sb.append("}");
6036 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006038 synchronized (mWindowMap) {
6039 if (mInputMethodManager == null && mHaveInputMethods) {
6040 IBinder b = ServiceManager.getService(
6041 Context.INPUT_METHOD_SERVICE);
6042 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6043 }
6044 }
6045 long ident = Binder.clearCallingIdentity();
6046 try {
6047 // Note: it is safe to call in to the input method manager
6048 // here because we are not holding our lock.
6049 if (mInputMethodManager != null) {
6050 mInputMethodManager.addClient(client, inputContext,
6051 mUid, mPid);
6052 } else {
6053 client.setUsingInputMethod(false);
6054 }
6055 client.asBinder().linkToDeath(this, 0);
6056 } catch (RemoteException e) {
6057 // The caller has died, so we can just forget about this.
6058 try {
6059 if (mInputMethodManager != null) {
6060 mInputMethodManager.removeClient(client);
6061 }
6062 } catch (RemoteException ee) {
6063 }
6064 } finally {
6065 Binder.restoreCallingIdentity(ident);
6066 }
6067 }
Romain Guy06882f82009-06-10 13:36:04 -07006068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006069 @Override
6070 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6071 throws RemoteException {
6072 try {
6073 return super.onTransact(code, data, reply, flags);
6074 } catch (RuntimeException e) {
6075 // Log all 'real' exceptions thrown to the caller
6076 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006077 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 }
6079 throw e;
6080 }
6081 }
6082
6083 public void binderDied() {
6084 // Note: it is safe to call in to the input method manager
6085 // here because we are not holding our lock.
6086 try {
6087 if (mInputMethodManager != null) {
6088 mInputMethodManager.removeClient(mClient);
6089 }
6090 } catch (RemoteException e) {
6091 }
6092 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006093 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 mClientDead = true;
6095 killSessionLocked();
6096 }
6097 }
6098
6099 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006100 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6101 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6102 outInputChannel);
6103 }
6104
6105 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006107 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006108 }
Romain Guy06882f82009-06-10 13:36:04 -07006109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 public void remove(IWindow window) {
6111 removeWindow(this, window);
6112 }
Romain Guy06882f82009-06-10 13:36:04 -07006113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006114 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6115 int requestedWidth, int requestedHeight, int viewFlags,
6116 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006117 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006118 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6119 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006121 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006122 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6123 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 }
Romain Guy06882f82009-06-10 13:36:04 -07006125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126 public void setTransparentRegion(IWindow window, Region region) {
6127 setTransparentRegionWindow(this, window, region);
6128 }
Romain Guy06882f82009-06-10 13:36:04 -07006129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 public void setInsets(IWindow window, int touchableInsets,
6131 Rect contentInsets, Rect visibleInsets) {
6132 setInsetsWindow(this, window, touchableInsets, contentInsets,
6133 visibleInsets);
6134 }
Romain Guy06882f82009-06-10 13:36:04 -07006135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006136 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6137 getWindowDisplayFrame(this, window, outDisplayFrame);
6138 }
Romain Guy06882f82009-06-10 13:36:04 -07006139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006141 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 TAG, "IWindow finishDrawing called for " + window);
6143 finishDrawingWindow(this, window);
6144 }
6145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006146 public void setInTouchMode(boolean mode) {
6147 synchronized(mWindowMap) {
6148 mInTouchMode = mode;
6149 }
6150 }
6151
6152 public boolean getInTouchMode() {
6153 synchronized(mWindowMap) {
6154 return mInTouchMode;
6155 }
6156 }
6157
6158 public boolean performHapticFeedback(IWindow window, int effectId,
6159 boolean always) {
6160 synchronized(mWindowMap) {
6161 long ident = Binder.clearCallingIdentity();
6162 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006163 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006164 windowForClientLocked(this, window, true),
6165 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006166 } finally {
6167 Binder.restoreCallingIdentity(ident);
6168 }
6169 }
6170 }
Romain Guy06882f82009-06-10 13:36:04 -07006171
Christopher Tatea53146c2010-09-07 11:57:52 -07006172 /* Drag/drop */
6173 public IBinder prepareDrag(IWindow window, boolean localOnly,
6174 int width, int height, Surface outSurface) {
6175 return prepareDragSurface(window, mSurfaceSession, localOnly,
6176 width, height, outSurface);
6177 }
6178
6179 public boolean performDrag(IWindow window, IBinder dragToken,
6180 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6181 ClipData data) {
6182 if (DEBUG_DRAG) {
6183 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6184 }
6185
6186 synchronized (mWindowMap) {
6187 if (mDragState == null) {
6188 Slog.w(TAG, "No drag prepared");
6189 throw new IllegalStateException("performDrag() without prepareDrag()");
6190 }
6191
6192 if (dragToken != mDragState.mToken) {
6193 Slog.w(TAG, "Performing mismatched drag");
6194 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6195 }
6196
6197 WindowState callingWin = windowForClientLocked(null, window, false);
6198 if (callingWin == null) {
6199 Slog.w(TAG, "Bad requesting window " + window);
6200 return false; // !!! TODO: throw here?
6201 }
6202
6203 // !!! TODO: if input is not still focused on the initiating window, fail
6204 // the drag initiation (e.g. an alarm window popped up just as the application
6205 // called performDrag()
6206
6207 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6208
Christopher Tate2c095f32010-10-04 14:13:40 -07006209 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6210 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006211
6212 mDragState.register();
6213 mInputMonitor.updateInputWindowsLw();
6214 mInputManager.transferTouchFocus(callingWin.mInputChannel,
6215 mDragState.mServerChannel);
6216
6217 mDragState.mData = data;
6218 mDragState.broadcastDragStartedLw();
6219
6220 // remember the thumb offsets for later
6221 mDragState.mThumbOffsetX = thumbCenterX;
6222 mDragState.mThumbOffsetY = thumbCenterY;
6223
6224 // Make the surface visible at the proper location
6225 final Surface surface = mDragState.mSurface;
6226 surface.openTransaction();
6227 try {
6228 surface.setPosition((int)(touchX - thumbCenterX),
6229 (int)(touchY - thumbCenterY));
6230 surface.setAlpha(.5f);
6231 surface.show();
6232 } finally {
6233 surface.closeTransaction();
6234 }
6235 }
6236
6237 return true; // success!
6238 }
6239
6240 public void dragRecipientEntered(IWindow window) {
6241 if (DEBUG_DRAG) {
6242 Slog.d(TAG, "Drag into new candidate view @ " + window);
6243 }
6244 }
6245
6246 public void dragRecipientExited(IWindow window) {
6247 if (DEBUG_DRAG) {
6248 Slog.d(TAG, "Drag from old candidate view @ " + window);
6249 }
6250 }
6251
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006252 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006253 synchronized(mWindowMap) {
6254 long ident = Binder.clearCallingIdentity();
6255 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006256 setWindowWallpaperPositionLocked(
6257 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006258 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006259 } finally {
6260 Binder.restoreCallingIdentity(ident);
6261 }
6262 }
6263 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006264
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006265 public void wallpaperOffsetsComplete(IBinder window) {
6266 WindowManagerService.this.wallpaperOffsetsComplete(window);
6267 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006268
Dianne Hackborn75804932009-10-20 20:15:20 -07006269 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6270 int z, Bundle extras, boolean sync) {
6271 synchronized(mWindowMap) {
6272 long ident = Binder.clearCallingIdentity();
6273 try {
6274 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006275 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006276 action, x, y, z, extras, sync);
6277 } finally {
6278 Binder.restoreCallingIdentity(ident);
6279 }
6280 }
6281 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006282
Dianne Hackborn75804932009-10-20 20:15:20 -07006283 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6284 WindowManagerService.this.wallpaperCommandComplete(window, result);
6285 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 void windowAddedLocked() {
6288 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006289 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 TAG, "First window added to " + this + ", creating SurfaceSession");
6291 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006292 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006293 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 mSessions.add(this);
6295 }
6296 mNumWindow++;
6297 }
6298
6299 void windowRemovedLocked() {
6300 mNumWindow--;
6301 killSessionLocked();
6302 }
Romain Guy06882f82009-06-10 13:36:04 -07006303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 void killSessionLocked() {
6305 if (mNumWindow <= 0 && mClientDead) {
6306 mSessions.remove(this);
6307 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006308 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 TAG, "Last window removed from " + this
6310 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006311 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006312 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 try {
6314 mSurfaceSession.kill();
6315 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006316 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 + mSurfaceSession + " in session " + this
6318 + ": " + e.toString());
6319 }
6320 mSurfaceSession = null;
6321 }
6322 }
6323 }
Romain Guy06882f82009-06-10 13:36:04 -07006324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006326 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6327 pw.print(" mClientDead="); pw.print(mClientDead);
6328 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 }
6330
6331 @Override
6332 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006333 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006334 }
6335 }
6336
6337 // -------------------------------------------------------------
6338 // Client Window State
6339 // -------------------------------------------------------------
6340
6341 private final class WindowState implements WindowManagerPolicy.WindowState {
6342 final Session mSession;
6343 final IWindow mClient;
6344 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006345 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 AppWindowToken mAppToken;
6347 AppWindowToken mTargetAppToken;
6348 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6349 final DeathRecipient mDeathRecipient;
6350 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006351 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006352 final int mBaseLayer;
6353 final int mSubLayer;
6354 final boolean mLayoutAttached;
6355 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006356 final boolean mIsWallpaper;
6357 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 int mViewVisibility;
6359 boolean mPolicyVisibility = true;
6360 boolean mPolicyVisibilityAfterAnim = true;
6361 boolean mAppFreezing;
6362 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006363 boolean mReportDestroySurface;
6364 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 boolean mAttachedHidden; // is our parent window hidden?
6366 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006367 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368 int mRequestedWidth;
6369 int mRequestedHeight;
6370 int mLastRequestedWidth;
6371 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 int mLayer;
6373 int mAnimLayer;
6374 int mLastLayer;
6375 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006376 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006377 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006378
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006379 int mLayoutSeq = -1;
6380
6381 Configuration mConfiguration = null;
6382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 // Actual frame shown on-screen (may be modified by animation)
6384 final Rect mShownFrame = new Rect();
6385 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006387 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006388 * Set when we have changed the size of the surface, to know that
6389 * we must tell them application to resize (and thus redraw itself).
6390 */
6391 boolean mSurfaceResized;
6392
6393 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 * Insets that determine the actually visible area
6395 */
6396 final Rect mVisibleInsets = new Rect();
6397 final Rect mLastVisibleInsets = new Rect();
6398 boolean mVisibleInsetsChanged;
6399
6400 /**
6401 * Insets that are covered by system windows
6402 */
6403 final Rect mContentInsets = new Rect();
6404 final Rect mLastContentInsets = new Rect();
6405 boolean mContentInsetsChanged;
6406
6407 /**
6408 * Set to true if we are waiting for this window to receive its
6409 * given internal insets before laying out other windows based on it.
6410 */
6411 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 /**
6414 * These are the content insets that were given during layout for
6415 * this window, to be applied to windows behind it.
6416 */
6417 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006419 /**
6420 * These are the visible insets that were given during layout for
6421 * this window, to be applied to windows behind it.
6422 */
6423 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 /**
6426 * Flag indicating whether the touchable region should be adjusted by
6427 * the visible insets; if false the area outside the visible insets is
6428 * NOT touchable, so we must use those to adjust the frame during hit
6429 * tests.
6430 */
6431 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006433 // Current transformation being applied.
6434 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6435 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6436 float mHScale=1, mVScale=1;
6437 float mLastHScale=1, mLastVScale=1;
6438 final Matrix mTmpMatrix = new Matrix();
6439
6440 // "Real" frame that the application sees.
6441 final Rect mFrame = new Rect();
6442 final Rect mLastFrame = new Rect();
6443
6444 final Rect mContainingFrame = new Rect();
6445 final Rect mDisplayFrame = new Rect();
6446 final Rect mContentFrame = new Rect();
6447 final Rect mVisibleFrame = new Rect();
6448
6449 float mShownAlpha = 1;
6450 float mAlpha = 1;
6451 float mLastAlpha = 1;
6452
6453 // Set to true if, when the window gets displayed, it should perform
6454 // an enter animation.
6455 boolean mEnterAnimationPending;
6456
6457 // Currently running animation.
6458 boolean mAnimating;
6459 boolean mLocalAnimating;
6460 Animation mAnimation;
6461 boolean mAnimationIsEntrance;
6462 boolean mHasTransformation;
6463 boolean mHasLocalTransformation;
6464 final Transformation mTransformation = new Transformation();
6465
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006466 // If a window showing a wallpaper: the requested offset for the
6467 // wallpaper; if a wallpaper window: the currently applied offset.
6468 float mWallpaperX = -1;
6469 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006470
6471 // If a window showing a wallpaper: what fraction of the offset
6472 // range corresponds to a full virtual screen.
6473 float mWallpaperXStep = -1;
6474 float mWallpaperYStep = -1;
6475
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006476 // Wallpaper windows: pixels offset based on above variables.
6477 int mXOffset;
6478 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006480 // This is set after IWindowSession.relayout() has been called at
6481 // least once for the window. It allows us to detect the situation
6482 // where we don't yet have a surface, but should have one soon, so
6483 // we can give the window focus before waiting for the relayout.
6484 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 // This is set after the Surface has been created but before the
6487 // window has been drawn. During this time the surface is hidden.
6488 boolean mDrawPending;
6489
6490 // This is set after the window has finished drawing for the first
6491 // time but before its surface is shown. The surface will be
6492 // displayed when the next layout is run.
6493 boolean mCommitDrawPending;
6494
6495 // This is set during the time after the window's drawing has been
6496 // committed, and before its surface is actually shown. It is used
6497 // to delay showing the surface until all windows in a token are ready
6498 // to be shown.
6499 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 // Set when the window has been shown in the screen the first time.
6502 boolean mHasDrawn;
6503
6504 // Currently running an exit animation?
6505 boolean mExiting;
6506
6507 // Currently on the mDestroySurface list?
6508 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 // Completely remove from window manager after exit animation?
6511 boolean mRemoveOnExit;
6512
6513 // Set when the orientation is changing and this window has not yet
6514 // been updated for the new orientation.
6515 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006517 // Is this window now (or just being) removed?
6518 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006519
Dianne Hackborn16064f92010-03-25 00:47:24 -07006520 // For debugging, this is the last information given to the surface flinger.
6521 boolean mSurfaceShown;
6522 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6523 int mSurfaceLayer;
6524 float mSurfaceAlpha;
6525
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006526 // Input channel
6527 InputChannel mInputChannel;
6528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 WindowState(Session s, IWindow c, WindowToken token,
6530 WindowState attachedWindow, WindowManager.LayoutParams a,
6531 int viewVisibility) {
6532 mSession = s;
6533 mClient = c;
6534 mToken = token;
6535 mAttrs.copyFrom(a);
6536 mViewVisibility = viewVisibility;
6537 DeathRecipient deathRecipient = new DeathRecipient();
6538 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006539 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 TAG, "Window " + this + " client=" + c.asBinder()
6541 + " token=" + token + " (" + mAttrs.token + ")");
6542 try {
6543 c.asBinder().linkToDeath(deathRecipient, 0);
6544 } catch (RemoteException e) {
6545 mDeathRecipient = null;
6546 mAttachedWindow = null;
6547 mLayoutAttached = false;
6548 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006549 mIsWallpaper = false;
6550 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 mBaseLayer = 0;
6552 mSubLayer = 0;
6553 return;
6554 }
6555 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006557 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6558 mAttrs.type <= LAST_SUB_WINDOW)) {
6559 // The multiplier here is to reserve space for multiple
6560 // windows in the same type layer.
6561 mBaseLayer = mPolicy.windowTypeToLayerLw(
6562 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6563 + TYPE_LAYER_OFFSET;
6564 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6565 mAttachedWindow = attachedWindow;
6566 mAttachedWindow.mChildWindows.add(this);
6567 mLayoutAttached = mAttrs.type !=
6568 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6569 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6570 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006571 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6572 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006573 } else {
6574 // The multiplier here is to reserve space for multiple
6575 // windows in the same type layer.
6576 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6577 * TYPE_LAYER_MULTIPLIER
6578 + TYPE_LAYER_OFFSET;
6579 mSubLayer = 0;
6580 mAttachedWindow = null;
6581 mLayoutAttached = false;
6582 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6583 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006584 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6585 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006586 }
6587
6588 WindowState appWin = this;
6589 while (appWin.mAttachedWindow != null) {
6590 appWin = mAttachedWindow;
6591 }
6592 WindowToken appToken = appWin.mToken;
6593 while (appToken.appWindowToken == null) {
6594 WindowToken parent = mTokenMap.get(appToken.token);
6595 if (parent == null || appToken == parent) {
6596 break;
6597 }
6598 appToken = parent;
6599 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006600 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 mAppToken = appToken.appWindowToken;
6602
6603 mSurface = null;
6604 mRequestedWidth = 0;
6605 mRequestedHeight = 0;
6606 mLastRequestedWidth = 0;
6607 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006608 mXOffset = 0;
6609 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 mLayer = 0;
6611 mAnimLayer = 0;
6612 mLastLayer = 0;
6613 }
6614
6615 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006616 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 TAG, "Attaching " + this + " token=" + mToken
6618 + ", list=" + mToken.windows);
6619 mSession.windowAddedLocked();
6620 }
6621
6622 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6623 mHaveFrame = true;
6624
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006625 final Rect container = mContainingFrame;
6626 container.set(pf);
6627
6628 final Rect display = mDisplayFrame;
6629 display.set(df);
6630
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006631 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006632 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006633 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6634 display.intersect(mCompatibleScreenFrame);
6635 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006636 }
6637
6638 final int pw = container.right - container.left;
6639 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640
6641 int w,h;
6642 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6643 w = mAttrs.width < 0 ? pw : mAttrs.width;
6644 h = mAttrs.height< 0 ? ph : mAttrs.height;
6645 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006646 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6647 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 }
Romain Guy06882f82009-06-10 13:36:04 -07006649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 final Rect content = mContentFrame;
6651 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 final Rect visible = mVisibleFrame;
6654 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006657 final int fw = frame.width();
6658 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6661 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6662
6663 Gravity.apply(mAttrs.gravity, w, h, container,
6664 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6665 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6666
6667 //System.out.println("Out: " + mFrame);
6668
6669 // Now make sure the window fits in the overall display.
6670 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 // Make sure the content and visible frames are inside of the
6673 // final window frame.
6674 if (content.left < frame.left) content.left = frame.left;
6675 if (content.top < frame.top) content.top = frame.top;
6676 if (content.right > frame.right) content.right = frame.right;
6677 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6678 if (visible.left < frame.left) visible.left = frame.left;
6679 if (visible.top < frame.top) visible.top = frame.top;
6680 if (visible.right > frame.right) visible.right = frame.right;
6681 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 final Rect contentInsets = mContentInsets;
6684 contentInsets.left = content.left-frame.left;
6685 contentInsets.top = content.top-frame.top;
6686 contentInsets.right = frame.right-content.right;
6687 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006689 final Rect visibleInsets = mVisibleInsets;
6690 visibleInsets.left = visible.left-frame.left;
6691 visibleInsets.top = visible.top-frame.top;
6692 visibleInsets.right = frame.right-visible.right;
6693 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006694
Dianne Hackborn284ac932009-08-28 10:34:25 -07006695 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6696 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006697 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006698 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 if (localLOGV) {
6701 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6702 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006703 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 + mRequestedWidth + ", mRequestedheight="
6705 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6706 + "): frame=" + mFrame.toShortString()
6707 + " ci=" + contentInsets.toShortString()
6708 + " vi=" + visibleInsets.toShortString());
6709 //}
6710 }
6711 }
Romain Guy06882f82009-06-10 13:36:04 -07006712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 public Rect getFrameLw() {
6714 return mFrame;
6715 }
6716
6717 public Rect getShownFrameLw() {
6718 return mShownFrame;
6719 }
6720
6721 public Rect getDisplayFrameLw() {
6722 return mDisplayFrame;
6723 }
6724
6725 public Rect getContentFrameLw() {
6726 return mContentFrame;
6727 }
6728
6729 public Rect getVisibleFrameLw() {
6730 return mVisibleFrame;
6731 }
6732
6733 public boolean getGivenInsetsPendingLw() {
6734 return mGivenInsetsPending;
6735 }
6736
6737 public Rect getGivenContentInsetsLw() {
6738 return mGivenContentInsets;
6739 }
Romain Guy06882f82009-06-10 13:36:04 -07006740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006741 public Rect getGivenVisibleInsetsLw() {
6742 return mGivenVisibleInsets;
6743 }
Romain Guy06882f82009-06-10 13:36:04 -07006744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 public WindowManager.LayoutParams getAttrs() {
6746 return mAttrs;
6747 }
6748
6749 public int getSurfaceLayer() {
6750 return mLayer;
6751 }
Romain Guy06882f82009-06-10 13:36:04 -07006752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753 public IApplicationToken getAppToken() {
6754 return mAppToken != null ? mAppToken.appToken : null;
6755 }
Jeff Brown349703e2010-06-22 01:27:15 -07006756
6757 public long getInputDispatchingTimeoutNanos() {
6758 return mAppToken != null
6759 ? mAppToken.inputDispatchingTimeoutNanos
6760 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762
6763 public boolean hasAppShownWindows() {
6764 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6765 }
6766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006767 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006768 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 TAG, "Setting animation in " + this + ": " + anim);
6770 mAnimating = false;
6771 mLocalAnimating = false;
6772 mAnimation = anim;
6773 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6774 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6775 }
6776
6777 public void clearAnimation() {
6778 if (mAnimation != null) {
6779 mAnimating = true;
6780 mLocalAnimating = false;
6781 mAnimation = null;
6782 }
6783 }
Romain Guy06882f82009-06-10 13:36:04 -07006784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 Surface createSurfaceLocked() {
6786 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006787 mReportDestroySurface = false;
6788 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 mDrawPending = true;
6790 mCommitDrawPending = false;
6791 mReadyToShow = false;
6792 if (mAppToken != null) {
6793 mAppToken.allDrawn = false;
6794 }
6795
6796 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006797 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 flags |= Surface.PUSH_BUFFERS;
6799 }
6800
6801 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6802 flags |= Surface.SECURE;
6803 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006804 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 TAG, "Creating surface in session "
6806 + mSession.mSurfaceSession + " window " + this
6807 + " w=" + mFrame.width()
6808 + " h=" + mFrame.height() + " format="
6809 + mAttrs.format + " flags=" + flags);
6810
6811 int w = mFrame.width();
6812 int h = mFrame.height();
6813 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
6814 // for a scaled surface, we always want the requested
6815 // size.
6816 w = mRequestedWidth;
6817 h = mRequestedHeight;
6818 }
6819
Romain Guy9825ec62009-10-01 00:58:09 -07006820 // Something is wrong and SurfaceFlinger will not like this,
6821 // try to revert to sane values
6822 if (w <= 0) w = 1;
6823 if (h <= 0) h = 1;
6824
Dianne Hackborn16064f92010-03-25 00:47:24 -07006825 mSurfaceShown = false;
6826 mSurfaceLayer = 0;
6827 mSurfaceAlpha = 1;
6828 mSurfaceX = 0;
6829 mSurfaceY = 0;
6830 mSurfaceW = w;
6831 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 try {
6833 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07006834 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08006835 mAttrs.getTitle().toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006836 0, w, h, mAttrs.format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006837 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006838 + mSurface + " IN SESSION "
6839 + mSession.mSurfaceSession
6840 + ": pid=" + mSession.mPid + " format="
6841 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006842 + Integer.toHexString(flags)
6843 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006844 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006845 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 reclaimSomeSurfaceMemoryLocked(this, "create");
6847 return null;
6848 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006849 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 return null;
6851 }
Romain Guy06882f82009-06-10 13:36:04 -07006852
Joe Onorato8a9b2202010-02-26 18:56:32 -08006853 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 TAG, "Got surface: " + mSurface
6855 + ", set left=" + mFrame.left + " top=" + mFrame.top
6856 + ", animLayer=" + mAnimLayer);
6857 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006858 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006859 if (SHOW_TRANSACTIONS) logSurface(this,
6860 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
6861 mFrame.width() + "x" + mFrame.height() + "), layer=" +
6862 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 }
6864 Surface.openTransaction();
6865 try {
6866 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07006867 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07006868 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07006869 mSurface.setPosition(mSurfaceX, mSurfaceY);
6870 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07006872 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 mSurface.hide();
6874 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006875 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 mSurface.setFlags(Surface.SURFACE_DITHER,
6877 Surface.SURFACE_DITHER);
6878 }
6879 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006880 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 reclaimSomeSurfaceMemoryLocked(this, "create-init");
6882 }
6883 mLastHidden = true;
6884 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006885 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 Surface.closeTransaction();
6887 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006888 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 TAG, "Created surface " + this);
6890 }
6891 return mSurface;
6892 }
Romain Guy06882f82009-06-10 13:36:04 -07006893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006894 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 if (mAppToken != null && this == mAppToken.startingWindow) {
6896 mAppToken.startingDisplayed = false;
6897 }
Romain Guy06882f82009-06-10 13:36:04 -07006898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006900 mDrawPending = false;
6901 mCommitDrawPending = false;
6902 mReadyToShow = false;
6903
6904 int i = mChildWindows.size();
6905 while (i > 0) {
6906 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006907 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006908 c.mAttachedHidden = true;
6909 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006910
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006911 if (mReportDestroySurface) {
6912 mReportDestroySurface = false;
6913 mSurfacePendingDestroy = true;
6914 try {
6915 mClient.dispatchGetNewSurface();
6916 // We'll really destroy on the next time around.
6917 return;
6918 } catch (RemoteException e) {
6919 }
6920 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006923 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006924 RuntimeException e = null;
6925 if (!HIDE_STACK_CRAWLS) {
6926 e = new RuntimeException();
6927 e.fillInStackTrace();
6928 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006929 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07006930 + mSurface + ", session " + mSession, e);
6931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006933 RuntimeException e = null;
6934 if (!HIDE_STACK_CRAWLS) {
6935 e = new RuntimeException();
6936 e.fillInStackTrace();
6937 }
6938 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006940 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006942 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 + " surface " + mSurface + " session " + mSession
6944 + ": " + e.toString());
6945 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006946
Dianne Hackborn16064f92010-03-25 00:47:24 -07006947 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006949 }
6950 }
6951
6952 boolean finishDrawingLocked() {
6953 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006954 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 TAG, "finishDrawingLocked: " + mSurface);
6956 mCommitDrawPending = true;
6957 mDrawPending = false;
6958 return true;
6959 }
6960 return false;
6961 }
6962
6963 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006964 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006965 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006967 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 }
6969 mCommitDrawPending = false;
6970 mReadyToShow = true;
6971 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
6972 final AppWindowToken atoken = mAppToken;
6973 if (atoken == null || atoken.allDrawn || starting) {
6974 performShowLocked();
6975 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006976 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 }
6978
6979 // This must be called while inside a transaction.
6980 boolean performShowLocked() {
6981 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006982 RuntimeException e = null;
6983 if (!HIDE_STACK_CRAWLS) {
6984 e = new RuntimeException();
6985 e.fillInStackTrace();
6986 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006987 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
6989 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
6990 }
6991 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006992 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
6993 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006994 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 + " during animation: policyVis=" + mPolicyVisibility
6996 + " attHidden=" + mAttachedHidden
6997 + " tok.hiddenRequested="
6998 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07006999 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 + (mAppToken != null ? mAppToken.hidden : false)
7001 + " animating=" + mAnimating
7002 + " tok animating="
7003 + (mAppToken != null ? mAppToken.animating : false));
7004 if (!showSurfaceRobustlyLocked(this)) {
7005 return false;
7006 }
7007 mLastAlpha = -1;
7008 mHasDrawn = true;
7009 mLastHidden = false;
7010 mReadyToShow = false;
7011 enableScreenIfNeededLocked();
7012
7013 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 int i = mChildWindows.size();
7016 while (i > 0) {
7017 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007018 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007019 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007020 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007021 if (c.mSurface != null) {
7022 c.performShowLocked();
7023 // It hadn't been shown, which means layout not
7024 // performed on it, so now we want to make sure to
7025 // do a layout. If called from within the transaction
7026 // loop, this will cause it to restart with a new
7027 // layout.
7028 mLayoutNeeded = true;
7029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 }
7031 }
Romain Guy06882f82009-06-10 13:36:04 -07007032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 if (mAttrs.type != TYPE_APPLICATION_STARTING
7034 && mAppToken != null) {
7035 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007036
Dianne Hackborn248b1882009-09-16 16:46:44 -07007037 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007038 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007039 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007041 // If this initial window is animating, stop it -- we
7042 // will do an animation to reveal it from behind the
7043 // starting window, so there is no need for it to also
7044 // be doing its own stuff.
7045 if (mAnimation != null) {
7046 mAnimation = null;
7047 // Make sure we clean up the animation.
7048 mAnimating = true;
7049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 mFinishedStarting.add(mAppToken);
7051 mH.sendEmptyMessage(H.FINISHED_STARTING);
7052 }
7053 mAppToken.updateReportedVisibilityLocked();
7054 }
7055 }
7056 return true;
7057 }
Romain Guy06882f82009-06-10 13:36:04 -07007058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 // This must be called while inside a transaction. Returns true if
7060 // there is more animation to run.
7061 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007062 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007063 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007065 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7066 mHasTransformation = true;
7067 mHasLocalTransformation = true;
7068 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007069 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007070 TAG, "Starting animation in " + this +
7071 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7072 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7073 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7074 mAnimation.setStartTime(currentTime);
7075 mLocalAnimating = true;
7076 mAnimating = true;
7077 }
7078 mTransformation.clear();
7079 final boolean more = mAnimation.getTransformation(
7080 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007081 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007082 TAG, "Stepped animation in " + this +
7083 ": more=" + more + ", xform=" + mTransformation);
7084 if (more) {
7085 // we're not done!
7086 return true;
7087 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007088 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 TAG, "Finished animation in " + this +
7090 " @ " + currentTime);
7091 mAnimation = null;
7092 //WindowManagerService.this.dump();
7093 }
7094 mHasLocalTransformation = false;
7095 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007096 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007097 // When our app token is animating, we kind-of pretend like
7098 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7099 // part of this check means that we will only do this if
7100 // our window is not currently exiting, or it is not
7101 // locally animating itself. The idea being that one that
7102 // is exiting and doing a local animation should be removed
7103 // once that animation is done.
7104 mAnimating = true;
7105 mHasTransformation = true;
7106 mTransformation.clear();
7107 return false;
7108 } else if (mHasTransformation) {
7109 // Little trick to get through the path below to act like
7110 // we have finished an animation.
7111 mAnimating = true;
7112 } else if (isAnimating()) {
7113 mAnimating = true;
7114 }
7115 } else if (mAnimation != null) {
7116 // If the display is frozen, and there is a pending animation,
7117 // clear it and make sure we run the cleanup code.
7118 mAnimating = true;
7119 mLocalAnimating = true;
7120 mAnimation = null;
7121 }
Romain Guy06882f82009-06-10 13:36:04 -07007122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007123 if (!mAnimating && !mLocalAnimating) {
7124 return false;
7125 }
7126
Joe Onorato8a9b2202010-02-26 18:56:32 -08007127 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007128 TAG, "Animation done in " + this + ": exiting=" + mExiting
7129 + ", reportedVisible="
7130 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 mAnimating = false;
7133 mLocalAnimating = false;
7134 mAnimation = null;
7135 mAnimLayer = mLayer;
7136 if (mIsImWindow) {
7137 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007138 } else if (mIsWallpaper) {
7139 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007140 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007141 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007142 + " anim layer: " + mAnimLayer);
7143 mHasTransformation = false;
7144 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007145 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7146 if (DEBUG_VISIBILITY) {
7147 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7148 + mPolicyVisibilityAfterAnim);
7149 }
7150 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7151 if (!mPolicyVisibility) {
7152 if (mCurrentFocus == this) {
7153 mFocusMayChange = true;
7154 }
7155 // Window is no longer visible -- make sure if we were waiting
7156 // for it to be displayed before enabling the display, that
7157 // we allow the display to be enabled now.
7158 enableScreenIfNeededLocked();
7159 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007161 mTransformation.clear();
7162 if (mHasDrawn
7163 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7164 && mAppToken != null
7165 && mAppToken.firstWindowDrawn
7166 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007167 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007168 + mToken + ": first real window done animating");
7169 mFinishedStarting.add(mAppToken);
7170 mH.sendEmptyMessage(H.FINISHED_STARTING);
7171 }
Romain Guy06882f82009-06-10 13:36:04 -07007172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007173 finishExit();
7174
7175 if (mAppToken != null) {
7176 mAppToken.updateReportedVisibilityLocked();
7177 }
7178
7179 return false;
7180 }
7181
7182 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007183 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 TAG, "finishExit in " + this
7185 + ": exiting=" + mExiting
7186 + " remove=" + mRemoveOnExit
7187 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 final int N = mChildWindows.size();
7190 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007191 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 }
Romain Guy06882f82009-06-10 13:36:04 -07007193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007194 if (!mExiting) {
7195 return;
7196 }
Romain Guy06882f82009-06-10 13:36:04 -07007197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 if (isWindowAnimating()) {
7199 return;
7200 }
7201
Joe Onorato8a9b2202010-02-26 18:56:32 -08007202 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007203 TAG, "Exit animation finished in " + this
7204 + ": remove=" + mRemoveOnExit);
7205 if (mSurface != null) {
7206 mDestroySurface.add(this);
7207 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007208 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007209 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 try {
7211 mSurface.hide();
7212 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007213 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 }
7215 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 }
7217 mExiting = false;
7218 if (mRemoveOnExit) {
7219 mPendingRemove.add(this);
7220 mRemoveOnExit = false;
7221 }
7222 }
Romain Guy06882f82009-06-10 13:36:04 -07007223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007224 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7225 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7226 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7227 if (dtdx < -.000001f || dtdx > .000001f) return false;
7228 if (dsdy < -.000001f || dsdy > .000001f) return false;
7229 return true;
7230 }
Romain Guy06882f82009-06-10 13:36:04 -07007231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007232 void computeShownFrameLocked() {
7233 final boolean selfTransformation = mHasLocalTransformation;
7234 Transformation attachedTransformation =
7235 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7236 ? mAttachedWindow.mTransformation : null;
7237 Transformation appTransformation =
7238 (mAppToken != null && mAppToken.hasTransformation)
7239 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007240
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007241 // Wallpapers are animated based on the "real" window they
7242 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007243 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007244 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007245 if (mWallpaperTarget.mHasLocalTransformation &&
7246 mWallpaperTarget.mAnimation != null &&
7247 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007248 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007249 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007250 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007251 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007252 }
7253 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007254 mWallpaperTarget.mAppToken.hasTransformation &&
7255 mWallpaperTarget.mAppToken.animation != null &&
7256 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007257 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007258 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007259 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007260 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007261 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007262 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 if (selfTransformation || attachedTransformation != null
7265 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007266 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 final Rect frame = mFrame;
7268 final float tmpFloats[] = mTmpFloats;
7269 final Matrix tmpMatrix = mTmpMatrix;
7270
7271 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007272 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007274 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007276 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007277 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007278 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 }
7280 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007281 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 }
7283
7284 // "convert" it into SurfaceFlinger's format
7285 // (a 2x2 matrix + an offset)
7286 // Here we must not transform the position of the surface
7287 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007288 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 tmpMatrix.getValues(tmpFloats);
7291 mDsDx = tmpFloats[Matrix.MSCALE_X];
7292 mDtDx = tmpFloats[Matrix.MSKEW_X];
7293 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7294 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007295 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7296 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007297 int w = frame.width();
7298 int h = frame.height();
7299 mShownFrame.set(x, y, x+w, y+h);
7300
7301 // Now set the alpha... but because our current hardware
7302 // can't do alpha transformation on a non-opaque surface,
7303 // turn it off if we are running an animation that is also
7304 // transforming since it is more important to have that
7305 // animation be smooth.
7306 mShownAlpha = mAlpha;
7307 if (!mLimitedAlphaCompositing
7308 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7309 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7310 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007311 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 if (selfTransformation) {
7313 mShownAlpha *= mTransformation.getAlpha();
7314 }
7315 if (attachedTransformation != null) {
7316 mShownAlpha *= attachedTransformation.getAlpha();
7317 }
7318 if (appTransformation != null) {
7319 mShownAlpha *= appTransformation.getAlpha();
7320 }
7321 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007322 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007323 }
Romain Guy06882f82009-06-10 13:36:04 -07007324
Joe Onorato8a9b2202010-02-26 18:56:32 -08007325 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 TAG, "Continuing animation in " + this +
7327 ": " + mShownFrame +
7328 ", alpha=" + mTransformation.getAlpha());
7329 return;
7330 }
Romain Guy06882f82009-06-10 13:36:04 -07007331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007333 if (mXOffset != 0 || mYOffset != 0) {
7334 mShownFrame.offset(mXOffset, mYOffset);
7335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007336 mShownAlpha = mAlpha;
7337 mDsDx = 1;
7338 mDtDx = 0;
7339 mDsDy = 0;
7340 mDtDy = 1;
7341 }
Romain Guy06882f82009-06-10 13:36:04 -07007342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 /**
7344 * Is this window visible? It is not visible if there is no
7345 * surface, or we are in the process of running an exit animation
7346 * that will remove the surface, or its app token has been hidden.
7347 */
7348 public boolean isVisibleLw() {
7349 final AppWindowToken atoken = mAppToken;
7350 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7351 && (atoken == null || !atoken.hiddenRequested)
7352 && !mExiting && !mDestroying;
7353 }
7354
7355 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007356 * Like {@link #isVisibleLw}, but also counts a window that is currently
7357 * "hidden" behind the keyguard as visible. This allows us to apply
7358 * things like window flags that impact the keyguard.
7359 * XXX I am starting to think we need to have ANOTHER visibility flag
7360 * for this "hidden behind keyguard" state rather than overloading
7361 * mPolicyVisibility. Ungh.
7362 */
7363 public boolean isVisibleOrBehindKeyguardLw() {
7364 final AppWindowToken atoken = mAppToken;
7365 return mSurface != null && !mAttachedHidden
7366 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007367 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007368 && !mExiting && !mDestroying;
7369 }
7370
7371 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 * Is this window visible, ignoring its app token? It is not visible
7373 * if there is no surface, or we are in the process of running an exit animation
7374 * that will remove the surface.
7375 */
7376 public boolean isWinVisibleLw() {
7377 final AppWindowToken atoken = mAppToken;
7378 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7379 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7380 && !mExiting && !mDestroying;
7381 }
7382
7383 /**
7384 * The same as isVisible(), but follows the current hidden state of
7385 * the associated app token, not the pending requested hidden state.
7386 */
7387 boolean isVisibleNow() {
7388 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007389 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007390 }
7391
7392 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007393 * Can this window possibly be a drag/drop target? The test here is
7394 * a combination of the above "visible now" with the check that the
7395 * Input Manager uses when discarding windows from input consideration.
7396 */
7397 boolean isPotentialDragTarget() {
7398 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7399 }
7400
7401 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 * Same as isVisible(), but we also count it as visible between the
7403 * call to IWindowSession.add() and the first relayout().
7404 */
7405 boolean isVisibleOrAdding() {
7406 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007407 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007408 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7409 && mPolicyVisibility && !mAttachedHidden
7410 && (atoken == null || !atoken.hiddenRequested)
7411 && !mExiting && !mDestroying;
7412 }
7413
7414 /**
7415 * Is this window currently on-screen? It is on-screen either if it
7416 * is visible or it is currently running an animation before no longer
7417 * being visible.
7418 */
7419 boolean isOnScreen() {
7420 final AppWindowToken atoken = mAppToken;
7421 if (atoken != null) {
7422 return mSurface != null && mPolicyVisibility && !mDestroying
7423 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007424 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 } else {
7426 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007427 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007428 }
7429 }
Romain Guy06882f82009-06-10 13:36:04 -07007430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 /**
7432 * Like isOnScreen(), but we don't return true if the window is part
7433 * of a transition that has not yet been started.
7434 */
7435 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007436 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007437 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007438 return false;
7439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007440 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007441 final boolean animating = atoken != null
7442 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007443 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007444 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7445 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007446 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007447 }
7448
7449 /** Is the window or its container currently animating? */
7450 boolean isAnimating() {
7451 final WindowState attached = mAttachedWindow;
7452 final AppWindowToken atoken = mAppToken;
7453 return mAnimation != null
7454 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007455 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 (atoken.animation != null
7457 || atoken.inPendingTransaction));
7458 }
7459
7460 /** Is this window currently animating? */
7461 boolean isWindowAnimating() {
7462 return mAnimation != null;
7463 }
7464
7465 /**
7466 * Like isOnScreen, but returns false if the surface hasn't yet
7467 * been drawn.
7468 */
7469 public boolean isDisplayedLw() {
7470 final AppWindowToken atoken = mAppToken;
7471 return mSurface != null && mPolicyVisibility && !mDestroying
7472 && !mDrawPending && !mCommitDrawPending
7473 && ((!mAttachedHidden &&
7474 (atoken == null || !atoken.hiddenRequested))
7475 || mAnimating);
7476 }
7477
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007478 /**
7479 * Returns true if the window has a surface that it has drawn a
7480 * complete UI in to.
7481 */
7482 public boolean isDrawnLw() {
7483 final AppWindowToken atoken = mAppToken;
7484 return mSurface != null && !mDestroying
7485 && !mDrawPending && !mCommitDrawPending;
7486 }
7487
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007488 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007489 * Return true if the window is opaque and fully drawn. This indicates
7490 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007491 */
7492 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007493 return (mAttrs.format == PixelFormat.OPAQUE
7494 || mAttrs.type == TYPE_WALLPAPER)
7495 && mSurface != null && mAnimation == null
7496 && (mAppToken == null || mAppToken.animation == null)
7497 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007498 }
7499
7500 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7501 return
7502 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007503 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7504 // only if it's visible
7505 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007506 // and only if the application fills the compatible screen
7507 mFrame.left <= mCompatibleScreenFrame.left &&
7508 mFrame.top <= mCompatibleScreenFrame.top &&
7509 mFrame.right >= mCompatibleScreenFrame.right &&
7510 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007511 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007512 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007513 }
7514
7515 boolean isFullscreen(int screenWidth, int screenHeight) {
7516 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007517 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 }
7519
7520 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007521 disposeInputChannel();
7522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007523 if (mAttachedWindow != null) {
7524 mAttachedWindow.mChildWindows.remove(this);
7525 }
7526 destroySurfaceLocked();
7527 mSession.windowRemovedLocked();
7528 try {
7529 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7530 } catch (RuntimeException e) {
7531 // Ignore if it has already been removed (usually because
7532 // we are doing this as part of processing a death note.)
7533 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007534 }
7535
7536 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007537 if (mInputChannel != null) {
7538 mInputManager.unregisterInputChannel(mInputChannel);
7539
7540 mInputChannel.dispose();
7541 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 }
7544
7545 private class DeathRecipient implements IBinder.DeathRecipient {
7546 public void binderDied() {
7547 try {
7548 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007549 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007550 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007551 if (win != null) {
7552 removeWindowLocked(mSession, win);
7553 }
7554 }
7555 } catch (IllegalArgumentException ex) {
7556 // This will happen if the window has already been
7557 // removed.
7558 }
7559 }
7560 }
7561
7562 /** Returns true if this window desires key events. */
7563 public final boolean canReceiveKeys() {
7564 return isVisibleOrAdding()
7565 && (mViewVisibility == View.VISIBLE)
7566 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7567 }
7568
7569 public boolean hasDrawnLw() {
7570 return mHasDrawn;
7571 }
7572
7573 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007574 return showLw(doAnimation, true);
7575 }
7576
7577 boolean showLw(boolean doAnimation, boolean requestAnim) {
7578 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7579 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007581 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007582 if (doAnimation) {
7583 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7584 + mPolicyVisibility + " mAnimation=" + mAnimation);
7585 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7586 doAnimation = false;
7587 } else if (mPolicyVisibility && mAnimation == null) {
7588 // Check for the case where we are currently visible and
7589 // not animating; we do not want to do animation at such a
7590 // point to become visible when we already are.
7591 doAnimation = false;
7592 }
7593 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007594 mPolicyVisibility = true;
7595 mPolicyVisibilityAfterAnim = true;
7596 if (doAnimation) {
7597 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7598 }
7599 if (requestAnim) {
7600 requestAnimationLocked(0);
7601 }
7602 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 }
7604
7605 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007606 return hideLw(doAnimation, true);
7607 }
7608
7609 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007610 if (doAnimation) {
7611 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7612 doAnimation = false;
7613 }
7614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007615 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7616 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007617 if (!current) {
7618 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007619 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007620 if (doAnimation) {
7621 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7622 if (mAnimation == null) {
7623 doAnimation = false;
7624 }
7625 }
7626 if (doAnimation) {
7627 mPolicyVisibilityAfterAnim = false;
7628 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007629 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007630 mPolicyVisibilityAfterAnim = false;
7631 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007632 // Window is no longer visible -- make sure if we were waiting
7633 // for it to be displayed before enabling the display, that
7634 // we allow the display to be enabled now.
7635 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007636 if (mCurrentFocus == this) {
7637 mFocusMayChange = true;
7638 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007639 }
7640 if (requestAnim) {
7641 requestAnimationLocked(0);
7642 }
7643 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007644 }
7645
7646 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007647 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7648 pw.print(" mClient="); pw.println(mClient.asBinder());
7649 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7650 if (mAttachedWindow != null || mLayoutAttached) {
7651 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7652 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7653 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007654 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7655 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7656 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007657 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7658 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007659 }
7660 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7661 pw.print(" mSubLayer="); pw.print(mSubLayer);
7662 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7663 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7664 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7665 pw.print("="); pw.print(mAnimLayer);
7666 pw.print(" mLastLayer="); pw.println(mLastLayer);
7667 if (mSurface != null) {
7668 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007669 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7670 pw.print(" layer="); pw.print(mSurfaceLayer);
7671 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7672 pw.print(" rect=("); pw.print(mSurfaceX);
7673 pw.print(","); pw.print(mSurfaceY);
7674 pw.print(") "); pw.print(mSurfaceW);
7675 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007676 }
7677 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7678 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7679 if (mAppToken != null) {
7680 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7681 }
7682 if (mTargetAppToken != null) {
7683 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7684 }
7685 pw.print(prefix); pw.print("mViewVisibility=0x");
7686 pw.print(Integer.toHexString(mViewVisibility));
7687 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007688 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7689 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007690 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7691 pw.print(prefix); pw.print("mPolicyVisibility=");
7692 pw.print(mPolicyVisibility);
7693 pw.print(" mPolicyVisibilityAfterAnim=");
7694 pw.print(mPolicyVisibilityAfterAnim);
7695 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7696 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007697 if (!mRelayoutCalled) {
7698 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7699 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007700 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007701 pw.print(" h="); pw.print(mRequestedHeight);
7702 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007703 if (mXOffset != 0 || mYOffset != 0) {
7704 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7705 pw.print(" y="); pw.println(mYOffset);
7706 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007707 pw.print(prefix); pw.print("mGivenContentInsets=");
7708 mGivenContentInsets.printShortString(pw);
7709 pw.print(" mGivenVisibleInsets=");
7710 mGivenVisibleInsets.printShortString(pw);
7711 pw.println();
7712 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7713 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7714 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7715 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007716 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007717 pw.print(prefix); pw.print("mShownFrame=");
7718 mShownFrame.printShortString(pw);
7719 pw.print(" last="); mLastShownFrame.printShortString(pw);
7720 pw.println();
7721 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7722 pw.print(" last="); mLastFrame.printShortString(pw);
7723 pw.println();
7724 pw.print(prefix); pw.print("mContainingFrame=");
7725 mContainingFrame.printShortString(pw);
7726 pw.print(" mDisplayFrame=");
7727 mDisplayFrame.printShortString(pw);
7728 pw.println();
7729 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7730 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7731 pw.println();
7732 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7733 pw.print(" last="); mLastContentInsets.printShortString(pw);
7734 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7735 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7736 pw.println();
7737 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7738 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7739 pw.print(" mAlpha="); pw.print(mAlpha);
7740 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7741 }
7742 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7743 || mAnimation != null) {
7744 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7745 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7746 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7747 pw.print(" mAnimation="); pw.println(mAnimation);
7748 }
7749 if (mHasTransformation || mHasLocalTransformation) {
7750 pw.print(prefix); pw.print("XForm: has=");
7751 pw.print(mHasTransformation);
7752 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7753 pw.print(" "); mTransformation.printShortString(pw);
7754 pw.println();
7755 }
7756 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7757 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7758 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7759 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7760 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7761 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7762 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7763 pw.print(" mDestroying="); pw.print(mDestroying);
7764 pw.print(" mRemoved="); pw.println(mRemoved);
7765 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007766 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007767 pw.print(prefix); pw.print("mOrientationChanging=");
7768 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007769 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7770 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007771 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007772 if (mHScale != 1 || mVScale != 1) {
7773 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7774 pw.print(" mVScale="); pw.println(mVScale);
7775 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007776 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007777 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7778 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7779 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007780 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7781 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7782 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007784 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007785
7786 String makeInputChannelName() {
7787 return Integer.toHexString(System.identityHashCode(this))
7788 + " " + mAttrs.getTitle();
7789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790
7791 @Override
7792 public String toString() {
7793 return "Window{"
7794 + Integer.toHexString(System.identityHashCode(this))
7795 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7796 }
7797 }
Romain Guy06882f82009-06-10 13:36:04 -07007798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 // -------------------------------------------------------------
7800 // Window Token State
7801 // -------------------------------------------------------------
7802
7803 class WindowToken {
7804 // The actual token.
7805 final IBinder token;
7806
7807 // The type of window this token is for, as per WindowManager.LayoutParams.
7808 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07007809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007810 // Set if this token was explicitly added by a client, so should
7811 // not be removed when all windows are removed.
7812 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07007813
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007814 // For printing.
7815 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07007816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 // If this is an AppWindowToken, this is non-null.
7818 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07007819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007820 // All of the windows associated with this token.
7821 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
7822
7823 // Is key dispatching paused for this token?
7824 boolean paused = false;
7825
7826 // Should this token's windows be hidden?
7827 boolean hidden;
7828
7829 // Temporary for finding which tokens no longer have visible windows.
7830 boolean hasVisible;
7831
Dianne Hackborna8f60182009-09-01 19:01:50 -07007832 // Set to true when this token is in a pending transaction where it
7833 // will be shown.
7834 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007835
Dianne Hackborna8f60182009-09-01 19:01:50 -07007836 // Set to true when this token is in a pending transaction where it
7837 // will be hidden.
7838 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007839
Dianne Hackborna8f60182009-09-01 19:01:50 -07007840 // Set to true when this token is in a pending transaction where its
7841 // windows will be put to the bottom of the list.
7842 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007843
Dianne Hackborna8f60182009-09-01 19:01:50 -07007844 // Set to true when this token is in a pending transaction where its
7845 // windows will be put to the top of the list.
7846 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007848 WindowToken(IBinder _token, int type, boolean _explicit) {
7849 token = _token;
7850 windowType = type;
7851 explicit = _explicit;
7852 }
7853
7854 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007855 pw.print(prefix); pw.print("token="); pw.println(token);
7856 pw.print(prefix); pw.print("windows="); pw.println(windows);
7857 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
7858 pw.print(" hidden="); pw.print(hidden);
7859 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007860 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
7861 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
7862 pw.print(" waitingToHide="); pw.print(waitingToHide);
7863 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
7864 pw.print(" sendingToTop="); pw.println(sendingToTop);
7865 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007866 }
7867
7868 @Override
7869 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007870 if (stringName == null) {
7871 StringBuilder sb = new StringBuilder();
7872 sb.append("WindowToken{");
7873 sb.append(Integer.toHexString(System.identityHashCode(this)));
7874 sb.append(" token="); sb.append(token); sb.append('}');
7875 stringName = sb.toString();
7876 }
7877 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007878 }
7879 };
7880
7881 class AppWindowToken extends WindowToken {
7882 // Non-null only for application tokens.
7883 final IApplicationToken appToken;
7884
7885 // All of the windows and child windows that are included in this
7886 // application token. Note this list is NOT sorted!
7887 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
7888
7889 int groupId = -1;
7890 boolean appFullscreen;
7891 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07007892
7893 // The input dispatching timeout for this application token in nanoseconds.
7894 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07007895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007896 // These are used for determining when all windows associated with
7897 // an activity have been drawn, so they can be made visible together
7898 // at the same time.
7899 int lastTransactionSequence = mTransactionSequence-1;
7900 int numInterestingWindows;
7901 int numDrawnWindows;
7902 boolean inPendingTransaction;
7903 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07007904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905 // Is this token going to be hidden in a little while? If so, it
7906 // won't be taken into account for setting the screen orientation.
7907 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 // Is this window's surface needed? This is almost like hidden, except
7910 // it will sometimes be true a little earlier: when the token has
7911 // been shown, but is still waiting for its app transition to execute
7912 // before making its windows shown.
7913 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07007914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007915 // Have we told the window clients to hide themselves?
7916 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07007917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007918 // Last visibility state we reported to the app token.
7919 boolean reportedVisible;
7920
7921 // Set to true when the token has been removed from the window mgr.
7922 boolean removed;
7923
7924 // Have we been asked to have this token keep the screen frozen?
7925 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07007926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 boolean animating;
7928 Animation animation;
7929 boolean hasTransformation;
7930 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07007931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 // Offset to the window of all layers in the token, for use by
7933 // AppWindowToken animations.
7934 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07007935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 // Information about an application starting window if displayed.
7937 StartingData startingData;
7938 WindowState startingWindow;
7939 View startingView;
7940 boolean startingDisplayed;
7941 boolean startingMoved;
7942 boolean firstWindowDrawn;
7943
7944 AppWindowToken(IApplicationToken _token) {
7945 super(_token.asBinder(),
7946 WindowManager.LayoutParams.TYPE_APPLICATION, true);
7947 appWindowToken = this;
7948 appToken = _token;
7949 }
Romain Guy06882f82009-06-10 13:36:04 -07007950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007951 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007952 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 TAG, "Setting animation in " + this + ": " + anim);
7954 animation = anim;
7955 animating = false;
7956 anim.restrictDuration(MAX_ANIMATION_DURATION);
7957 anim.scaleCurrentDuration(mTransitionAnimationScale);
7958 int zorder = anim.getZAdjustment();
7959 int adj = 0;
7960 if (zorder == Animation.ZORDER_TOP) {
7961 adj = TYPE_LAYER_OFFSET;
7962 } else if (zorder == Animation.ZORDER_BOTTOM) {
7963 adj = -TYPE_LAYER_OFFSET;
7964 }
Romain Guy06882f82009-06-10 13:36:04 -07007965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 if (animLayerAdjustment != adj) {
7967 animLayerAdjustment = adj;
7968 updateLayers();
7969 }
7970 }
Romain Guy06882f82009-06-10 13:36:04 -07007971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007972 public void setDummyAnimation() {
7973 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007974 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 TAG, "Setting dummy animation in " + this);
7976 animation = sDummyAnimation;
7977 }
7978 }
7979
7980 public void clearAnimation() {
7981 if (animation != null) {
7982 animation = null;
7983 animating = true;
7984 }
7985 }
Romain Guy06882f82009-06-10 13:36:04 -07007986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 void updateLayers() {
7988 final int N = allAppWindows.size();
7989 final int adj = animLayerAdjustment;
7990 for (int i=0; i<N; i++) {
7991 WindowState w = allAppWindows.get(i);
7992 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007993 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007994 + w.mAnimLayer);
7995 if (w == mInputMethodTarget) {
7996 setInputMethodAnimLayerAdjustment(adj);
7997 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007998 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007999 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001 }
8002 }
Romain Guy06882f82009-06-10 13:36:04 -07008003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 void sendAppVisibilityToClients() {
8005 final int N = allAppWindows.size();
8006 for (int i=0; i<N; i++) {
8007 WindowState win = allAppWindows.get(i);
8008 if (win == startingWindow && clientHidden) {
8009 // Don't hide the starting window.
8010 continue;
8011 }
8012 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008013 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008014 "Setting visibility of " + win + ": " + (!clientHidden));
8015 win.mClient.dispatchAppVisibility(!clientHidden);
8016 } catch (RemoteException e) {
8017 }
8018 }
8019 }
Romain Guy06882f82009-06-10 13:36:04 -07008020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008021 void showAllWindowsLocked() {
8022 final int NW = allAppWindows.size();
8023 for (int i=0; i<NW; i++) {
8024 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008025 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 "performing show on: " + w);
8027 w.performShowLocked();
8028 }
8029 }
Romain Guy06882f82009-06-10 13:36:04 -07008030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008031 // This must be called while inside a transaction.
8032 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008033 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 if (animation == sDummyAnimation) {
8037 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008038 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 // when it is really time to animate, this will be set to
8040 // a real animation and the next call will execute normally.
8041 return false;
8042 }
Romain Guy06882f82009-06-10 13:36:04 -07008043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8045 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008046 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 TAG, "Starting animation in " + this +
8048 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8049 + " scale=" + mTransitionAnimationScale
8050 + " allDrawn=" + allDrawn + " animating=" + animating);
8051 animation.initialize(dw, dh, dw, dh);
8052 animation.setStartTime(currentTime);
8053 animating = true;
8054 }
8055 transformation.clear();
8056 final boolean more = animation.getTransformation(
8057 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008058 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008059 TAG, "Stepped animation in " + this +
8060 ": more=" + more + ", xform=" + transformation);
8061 if (more) {
8062 // we're done!
8063 hasTransformation = true;
8064 return true;
8065 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008066 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008067 TAG, "Finished animation in " + this +
8068 " @ " + currentTime);
8069 animation = null;
8070 }
8071 } else if (animation != null) {
8072 // If the display is frozen, and there is a pending animation,
8073 // clear it and make sure we run the cleanup code.
8074 animating = true;
8075 animation = null;
8076 }
8077
8078 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 if (!animating) {
8081 return false;
8082 }
8083
8084 clearAnimation();
8085 animating = false;
8086 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8087 moveInputMethodWindowsIfNeededLocked(true);
8088 }
Romain Guy06882f82009-06-10 13:36:04 -07008089
Joe Onorato8a9b2202010-02-26 18:56:32 -08008090 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 TAG, "Animation done in " + this
8092 + ": reportedVisible=" + reportedVisible);
8093
8094 transformation.clear();
8095 if (animLayerAdjustment != 0) {
8096 animLayerAdjustment = 0;
8097 updateLayers();
8098 }
Romain Guy06882f82009-06-10 13:36:04 -07008099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 final int N = windows.size();
8101 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008102 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 }
8104 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008106 return false;
8107 }
8108
8109 void updateReportedVisibilityLocked() {
8110 if (appToken == null) {
8111 return;
8112 }
Romain Guy06882f82009-06-10 13:36:04 -07008113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008114 int numInteresting = 0;
8115 int numVisible = 0;
8116 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008117
Joe Onorato8a9b2202010-02-26 18:56:32 -08008118 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008119 final int N = allAppWindows.size();
8120 for (int i=0; i<N; i++) {
8121 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008122 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008123 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008124 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8125 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008126 continue;
8127 }
8128 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008129 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008130 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008132 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008133 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 + " pv=" + win.mPolicyVisibility
8135 + " dp=" + win.mDrawPending
8136 + " cdp=" + win.mCommitDrawPending
8137 + " ah=" + win.mAttachedHidden
8138 + " th="
8139 + (win.mAppToken != null
8140 ? win.mAppToken.hiddenRequested : false)
8141 + " a=" + win.mAnimating);
8142 }
8143 }
8144 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008145 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 if (!win.isAnimating()) {
8147 numVisible++;
8148 }
8149 nowGone = false;
8150 } else if (win.isAnimating()) {
8151 nowGone = false;
8152 }
8153 }
Romain Guy06882f82009-06-10 13:36:04 -07008154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008156 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157 + numInteresting + " visible=" + numVisible);
8158 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008159 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 TAG, "Visibility changed in " + this
8161 + ": vis=" + nowVisible);
8162 reportedVisible = nowVisible;
8163 Message m = mH.obtainMessage(
8164 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8165 nowVisible ? 1 : 0,
8166 nowGone ? 1 : 0,
8167 this);
8168 mH.sendMessage(m);
8169 }
8170 }
Romain Guy06882f82009-06-10 13:36:04 -07008171
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008172 WindowState findMainWindow() {
8173 int j = windows.size();
8174 while (j > 0) {
8175 j--;
8176 WindowState win = windows.get(j);
8177 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8178 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8179 return win;
8180 }
8181 }
8182 return null;
8183 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 void dump(PrintWriter pw, String prefix) {
8186 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008187 if (appToken != null) {
8188 pw.print(prefix); pw.println("app=true");
8189 }
8190 if (allAppWindows.size() > 0) {
8191 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8192 }
8193 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008194 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008195 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8196 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8197 pw.print(" clientHidden="); pw.print(clientHidden);
8198 pw.print(" willBeHidden="); pw.print(willBeHidden);
8199 pw.print(" reportedVisible="); pw.println(reportedVisible);
8200 if (paused || freezingScreen) {
8201 pw.print(prefix); pw.print("paused="); pw.print(paused);
8202 pw.print(" freezingScreen="); pw.println(freezingScreen);
8203 }
8204 if (numInterestingWindows != 0 || numDrawnWindows != 0
8205 || inPendingTransaction || allDrawn) {
8206 pw.print(prefix); pw.print("numInterestingWindows=");
8207 pw.print(numInterestingWindows);
8208 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8209 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8210 pw.print(" allDrawn="); pw.println(allDrawn);
8211 }
8212 if (animating || animation != null) {
8213 pw.print(prefix); pw.print("animating="); pw.print(animating);
8214 pw.print(" animation="); pw.println(animation);
8215 }
8216 if (animLayerAdjustment != 0) {
8217 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8218 }
8219 if (hasTransformation) {
8220 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8221 pw.print(" transformation="); transformation.printShortString(pw);
8222 pw.println();
8223 }
8224 if (startingData != null || removed || firstWindowDrawn) {
8225 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8226 pw.print(" removed="); pw.print(removed);
8227 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8228 }
8229 if (startingWindow != null || startingView != null
8230 || startingDisplayed || startingMoved) {
8231 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8232 pw.print(" startingView="); pw.print(startingView);
8233 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8234 pw.print(" startingMoved"); pw.println(startingMoved);
8235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008236 }
8237
8238 @Override
8239 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008240 if (stringName == null) {
8241 StringBuilder sb = new StringBuilder();
8242 sb.append("AppWindowToken{");
8243 sb.append(Integer.toHexString(System.identityHashCode(this)));
8244 sb.append(" token="); sb.append(token); sb.append('}');
8245 stringName = sb.toString();
8246 }
8247 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008248 }
8249 }
Romain Guy06882f82009-06-10 13:36:04 -07008250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008251 // -------------------------------------------------------------
8252 // DummyAnimation
8253 // -------------------------------------------------------------
8254
8255 // This is an animation that does nothing: it just immediately finishes
8256 // itself every time it is called. It is used as a stub animation in cases
8257 // where we want to synchronize multiple things that may be animating.
8258 static final class DummyAnimation extends Animation {
8259 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8260 return false;
8261 }
8262 }
8263 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 // -------------------------------------------------------------
8266 // Async Handler
8267 // -------------------------------------------------------------
8268
8269 static final class StartingData {
8270 final String pkg;
8271 final int theme;
8272 final CharSequence nonLocalizedLabel;
8273 final int labelRes;
8274 final int icon;
Romain Guy06882f82009-06-10 13:36:04 -07008275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
8277 int _labelRes, int _icon) {
8278 pkg = _pkg;
8279 theme = _theme;
8280 nonLocalizedLabel = _nonLocalizedLabel;
8281 labelRes = _labelRes;
8282 icon = _icon;
8283 }
8284 }
8285
8286 private final class H extends Handler {
8287 public static final int REPORT_FOCUS_CHANGE = 2;
8288 public static final int REPORT_LOSING_FOCUS = 3;
8289 public static final int ANIMATE = 4;
8290 public static final int ADD_STARTING = 5;
8291 public static final int REMOVE_STARTING = 6;
8292 public static final int FINISHED_STARTING = 7;
8293 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008294 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8295 public static final int HOLD_SCREEN_CHANGED = 12;
8296 public static final int APP_TRANSITION_TIMEOUT = 13;
8297 public static final int PERSIST_ANIMATION_SCALE = 14;
8298 public static final int FORCE_GC = 15;
8299 public static final int ENABLE_SCREEN = 16;
8300 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008301 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008302 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008303 public static final int DRAG_START_TIMEOUT = 20;
Romain Guy06882f82009-06-10 13:36:04 -07008304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 public H() {
8308 }
Romain Guy06882f82009-06-10 13:36:04 -07008309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008310 @Override
8311 public void handleMessage(Message msg) {
8312 switch (msg.what) {
8313 case REPORT_FOCUS_CHANGE: {
8314 WindowState lastFocus;
8315 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008317 synchronized(mWindowMap) {
8318 lastFocus = mLastFocus;
8319 newFocus = mCurrentFocus;
8320 if (lastFocus == newFocus) {
8321 // Focus is not changing, so nothing to do.
8322 return;
8323 }
8324 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008325 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 // + " to " + newFocus);
8327 if (newFocus != null && lastFocus != null
8328 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008329 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008330 mLosingFocus.add(lastFocus);
8331 lastFocus = null;
8332 }
8333 }
8334
8335 if (lastFocus != newFocus) {
8336 //System.out.println("Changing focus from " + lastFocus
8337 // + " to " + newFocus);
8338 if (newFocus != null) {
8339 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008340 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8342 } catch (RemoteException e) {
8343 // Ignore if process has died.
8344 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008345 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 }
8347
8348 if (lastFocus != null) {
8349 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008350 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008351 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8352 } catch (RemoteException e) {
8353 // Ignore if process has died.
8354 }
8355 }
8356 }
8357 } break;
8358
8359 case REPORT_LOSING_FOCUS: {
8360 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 synchronized(mWindowMap) {
8363 losers = mLosingFocus;
8364 mLosingFocus = new ArrayList<WindowState>();
8365 }
8366
8367 final int N = losers.size();
8368 for (int i=0; i<N; i++) {
8369 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008370 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8372 } catch (RemoteException e) {
8373 // Ignore if process has died.
8374 }
8375 }
8376 } break;
8377
8378 case ANIMATE: {
8379 synchronized(mWindowMap) {
8380 mAnimationPending = false;
8381 performLayoutAndPlaceSurfacesLocked();
8382 }
8383 } break;
8384
8385 case ADD_STARTING: {
8386 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8387 final StartingData sd = wtoken.startingData;
8388
8389 if (sd == null) {
8390 // Animation has been canceled... do nothing.
8391 return;
8392 }
Romain Guy06882f82009-06-10 13:36:04 -07008393
Joe Onorato8a9b2202010-02-26 18:56:32 -08008394 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008395 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 View view = null;
8398 try {
8399 view = mPolicy.addStartingWindow(
8400 wtoken.token, sd.pkg,
8401 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
8402 sd.icon);
8403 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008404 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 }
8406
8407 if (view != null) {
8408 boolean abort = false;
8409
8410 synchronized(mWindowMap) {
8411 if (wtoken.removed || wtoken.startingData == null) {
8412 // If the window was successfully added, then
8413 // we need to remove it.
8414 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008415 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008416 "Aborted starting " + wtoken
8417 + ": removed=" + wtoken.removed
8418 + " startingData=" + wtoken.startingData);
8419 wtoken.startingWindow = null;
8420 wtoken.startingData = null;
8421 abort = true;
8422 }
8423 } else {
8424 wtoken.startingView = view;
8425 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008426 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427 "Added starting " + wtoken
8428 + ": startingWindow="
8429 + wtoken.startingWindow + " startingView="
8430 + wtoken.startingView);
8431 }
8432
8433 if (abort) {
8434 try {
8435 mPolicy.removeStartingWindow(wtoken.token, view);
8436 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008437 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 }
8439 }
8440 }
8441 } break;
8442
8443 case REMOVE_STARTING: {
8444 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8445 IBinder token = null;
8446 View view = null;
8447 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008448 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008449 + wtoken + ": startingWindow="
8450 + wtoken.startingWindow + " startingView="
8451 + wtoken.startingView);
8452 if (wtoken.startingWindow != null) {
8453 view = wtoken.startingView;
8454 token = wtoken.token;
8455 wtoken.startingData = null;
8456 wtoken.startingView = null;
8457 wtoken.startingWindow = null;
8458 }
8459 }
8460 if (view != null) {
8461 try {
8462 mPolicy.removeStartingWindow(token, view);
8463 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008464 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 }
8466 }
8467 } break;
8468
8469 case FINISHED_STARTING: {
8470 IBinder token = null;
8471 View view = null;
8472 while (true) {
8473 synchronized (mWindowMap) {
8474 final int N = mFinishedStarting.size();
8475 if (N <= 0) {
8476 break;
8477 }
8478 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8479
Joe Onorato8a9b2202010-02-26 18:56:32 -08008480 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008481 "Finished starting " + wtoken
8482 + ": startingWindow=" + wtoken.startingWindow
8483 + " startingView=" + wtoken.startingView);
8484
8485 if (wtoken.startingWindow == null) {
8486 continue;
8487 }
8488
8489 view = wtoken.startingView;
8490 token = wtoken.token;
8491 wtoken.startingData = null;
8492 wtoken.startingView = null;
8493 wtoken.startingWindow = null;
8494 }
8495
8496 try {
8497 mPolicy.removeStartingWindow(token, view);
8498 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008499 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 }
8501 }
8502 } break;
8503
8504 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8505 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8506
8507 boolean nowVisible = msg.arg1 != 0;
8508 boolean nowGone = msg.arg2 != 0;
8509
8510 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008511 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512 TAG, "Reporting visible in " + wtoken
8513 + " visible=" + nowVisible
8514 + " gone=" + nowGone);
8515 if (nowVisible) {
8516 wtoken.appToken.windowsVisible();
8517 } else {
8518 wtoken.appToken.windowsGone();
8519 }
8520 } catch (RemoteException ex) {
8521 }
8522 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 case WINDOW_FREEZE_TIMEOUT: {
8525 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008526 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527 int i = mWindows.size();
8528 while (i > 0) {
8529 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008530 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531 if (w.mOrientationChanging) {
8532 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008533 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 }
8535 }
8536 performLayoutAndPlaceSurfacesLocked();
8537 }
8538 break;
8539 }
Romain Guy06882f82009-06-10 13:36:04 -07008540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 case HOLD_SCREEN_CHANGED: {
8542 Session oldHold;
8543 Session newHold;
8544 synchronized (mWindowMap) {
8545 oldHold = mLastReportedHold;
8546 newHold = (Session)msg.obj;
8547 mLastReportedHold = newHold;
8548 }
Romain Guy06882f82009-06-10 13:36:04 -07008549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008550 if (oldHold != newHold) {
8551 try {
8552 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008553 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008554 "window",
8555 BatteryStats.WAKE_TYPE_WINDOW);
8556 }
8557 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008558 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008559 "window",
8560 BatteryStats.WAKE_TYPE_WINDOW);
8561 }
8562 } catch (RemoteException e) {
8563 }
8564 }
8565 break;
8566 }
Romain Guy06882f82009-06-10 13:36:04 -07008567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 case APP_TRANSITION_TIMEOUT: {
8569 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008570 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008571 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 "*** APP TRANSITION TIMEOUT");
8573 mAppTransitionReady = true;
8574 mAppTransitionTimeout = true;
8575 performLayoutAndPlaceSurfacesLocked();
8576 }
8577 }
8578 break;
8579 }
Romain Guy06882f82009-06-10 13:36:04 -07008580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008581 case PERSIST_ANIMATION_SCALE: {
8582 Settings.System.putFloat(mContext.getContentResolver(),
8583 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8584 Settings.System.putFloat(mContext.getContentResolver(),
8585 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8586 break;
8587 }
Romain Guy06882f82009-06-10 13:36:04 -07008588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 case FORCE_GC: {
8590 synchronized(mWindowMap) {
8591 if (mAnimationPending) {
8592 // If we are animating, don't do the gc now but
8593 // delay a bit so we don't interrupt the animation.
8594 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8595 2000);
8596 return;
8597 }
8598 // If we are currently rotating the display, it will
8599 // schedule a new message when done.
8600 if (mDisplayFrozen) {
8601 return;
8602 }
8603 mFreezeGcPending = 0;
8604 }
8605 Runtime.getRuntime().gc();
8606 break;
8607 }
Romain Guy06882f82009-06-10 13:36:04 -07008608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008609 case ENABLE_SCREEN: {
8610 performEnableScreen();
8611 break;
8612 }
Romain Guy06882f82009-06-10 13:36:04 -07008613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 case APP_FREEZE_TIMEOUT: {
8615 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008616 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617 int i = mAppTokens.size();
8618 while (i > 0) {
8619 i--;
8620 AppWindowToken tok = mAppTokens.get(i);
8621 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008622 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008623 unsetAppFreezingScreenLocked(tok, true, true);
8624 }
8625 }
8626 }
8627 break;
8628 }
Romain Guy06882f82009-06-10 13:36:04 -07008629
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008630 case SEND_NEW_CONFIGURATION: {
8631 removeMessages(SEND_NEW_CONFIGURATION);
8632 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008633 break;
8634 }
Romain Guy06882f82009-06-10 13:36:04 -07008635
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008636 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008637 if (mWindowsChanged) {
8638 synchronized (mWindowMap) {
8639 mWindowsChanged = false;
8640 }
8641 notifyWindowsChanged();
8642 }
8643 break;
8644 }
8645
Christopher Tatea53146c2010-09-07 11:57:52 -07008646 case DRAG_START_TIMEOUT: {
8647 IBinder win = (IBinder)msg.obj;
8648 if (DEBUG_DRAG) {
8649 Slog.w(TAG, "Timeout starting drag by win " + win);
8650 }
8651 synchronized (mWindowMap) {
8652 // !!! TODO: ANR the app that has failed to start the drag in time
8653 if (mDragState != null) {
8654 mDragState.reset();
8655 mDragState = null;
8656 }
8657 }
8658 }
8659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008660 }
8661 }
8662 }
8663
8664 // -------------------------------------------------------------
8665 // IWindowManager API
8666 // -------------------------------------------------------------
8667
8668 public IWindowSession openSession(IInputMethodClient client,
8669 IInputContext inputContext) {
8670 if (client == null) throw new IllegalArgumentException("null client");
8671 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008672 Session session = new Session(client, inputContext);
8673 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
8675
8676 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8677 synchronized (mWindowMap) {
8678 // The focus for the client is the window immediately below
8679 // where we would place the input method window.
8680 int idx = findDesiredInputMethodWindowIndexLocked(false);
8681 WindowState imFocus;
8682 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008683 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008684 if (imFocus != null) {
8685 if (imFocus.mSession.mClient != null &&
8686 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8687 return true;
8688 }
8689 }
8690 }
8691 }
8692 return false;
8693 }
Romain Guy06882f82009-06-10 13:36:04 -07008694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008695 // -------------------------------------------------------------
8696 // Internals
8697 // -------------------------------------------------------------
8698
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008699 final WindowState windowForClientLocked(Session session, IWindow client,
8700 boolean throwOnError) {
8701 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 }
Romain Guy06882f82009-06-10 13:36:04 -07008703
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008704 final WindowState windowForClientLocked(Session session, IBinder client,
8705 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008707 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 TAG, "Looking up client " + client + ": " + win);
8709 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008710 RuntimeException ex = new IllegalArgumentException(
8711 "Requested window " + client + " does not exist");
8712 if (throwOnError) {
8713 throw ex;
8714 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008715 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008716 return null;
8717 }
8718 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008719 RuntimeException ex = new IllegalArgumentException(
8720 "Requested window " + client + " is in session " +
8721 win.mSession + ", not " + session);
8722 if (throwOnError) {
8723 throw ex;
8724 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008725 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008726 return null;
8727 }
8728
8729 return win;
8730 }
8731
Dianne Hackborna8f60182009-09-01 19:01:50 -07008732 final void rebuildAppWindowListLocked() {
8733 int NW = mWindows.size();
8734 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008735 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008736 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008737
Dianne Hackborna8f60182009-09-01 19:01:50 -07008738 // First remove all existing app windows.
8739 i=0;
8740 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07008741 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008742 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07008743 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008744 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008745 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008746 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008747 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008748 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008749 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008750 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8751 && lastWallpaper == i-1) {
8752 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008753 }
8754 i++;
8755 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008756
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008757 // The wallpaper window(s) typically live at the bottom of the stack,
8758 // so skip them before adding app tokens.
8759 lastWallpaper++;
8760 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008761
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008762 // First add all of the exiting app tokens... these are no longer
8763 // in the main app list, but still have windows shown. We put them
8764 // in the back because now that the animation is over we no longer
8765 // will care about them.
8766 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008767 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008768 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8769 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008770
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008771 // And add in the still active app tokens in Z order.
8772 NT = mAppTokens.size();
8773 for (int j=0; j<NT; j++) {
8774 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008775 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008776
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008777 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008778 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008779 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008780 + " windows but added " + i);
8781 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008782 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008784 private final void assignLayersLocked() {
8785 int N = mWindows.size();
8786 int curBaseLayer = 0;
8787 int curLayer = 0;
8788 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008791 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008792 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8793 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008794 curLayer += WINDOW_LAYER_MULTIPLIER;
8795 w.mLayer = curLayer;
8796 } else {
8797 curBaseLayer = curLayer = w.mBaseLayer;
8798 w.mLayer = curLayer;
8799 }
8800 if (w.mTargetAppToken != null) {
8801 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
8802 } else if (w.mAppToken != null) {
8803 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
8804 } else {
8805 w.mAnimLayer = w.mLayer;
8806 }
8807 if (w.mIsImWindow) {
8808 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008809 } else if (w.mIsWallpaper) {
8810 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008811 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008812 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008813 + w.mAnimLayer);
8814 //System.out.println(
8815 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8816 }
8817 }
8818
8819 private boolean mInLayout = false;
8820 private final void performLayoutAndPlaceSurfacesLocked() {
8821 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008822 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008823 throw new RuntimeException("Recursive call!");
8824 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008825 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 return;
8827 }
8828
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008829 if (mWaitingForConfig) {
8830 // Our configuration has changed (most likely rotation), but we
8831 // don't yet have the complete configuration to report to
8832 // applications. Don't do any window layout until we have it.
8833 return;
8834 }
8835
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008836 if (mDisplay == null) {
8837 // Not yet initialized, nothing to do.
8838 return;
8839 }
8840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 boolean recoveringMemory = false;
8842 if (mForceRemoves != null) {
8843 recoveringMemory = true;
8844 // Wait a little it for things to settle down, and off we go.
8845 for (int i=0; i<mForceRemoves.size(); i++) {
8846 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008847 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008848 removeWindowInnerLocked(ws.mSession, ws);
8849 }
8850 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008851 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852 Object tmp = new Object();
8853 synchronized (tmp) {
8854 try {
8855 tmp.wait(250);
8856 } catch (InterruptedException e) {
8857 }
8858 }
8859 }
Romain Guy06882f82009-06-10 13:36:04 -07008860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008861 mInLayout = true;
8862 try {
8863 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07008864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008865 int i = mPendingRemove.size()-1;
8866 if (i >= 0) {
8867 while (i >= 0) {
8868 WindowState w = mPendingRemove.get(i);
8869 removeWindowInnerLocked(w.mSession, w);
8870 i--;
8871 }
8872 mPendingRemove.clear();
8873
8874 mInLayout = false;
8875 assignLayersLocked();
8876 mLayoutNeeded = true;
8877 performLayoutAndPlaceSurfacesLocked();
8878
8879 } else {
8880 mInLayout = false;
8881 if (mLayoutNeeded) {
8882 requestAnimationLocked(0);
8883 }
8884 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008885 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008886 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8887 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008889 } catch (RuntimeException e) {
8890 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008891 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008892 }
8893 }
8894
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008895 private final int performLayoutLockedInner() {
8896 if (!mLayoutNeeded) {
8897 return 0;
8898 }
8899
8900 mLayoutNeeded = false;
8901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008902 final int dw = mDisplay.getWidth();
8903 final int dh = mDisplay.getHeight();
8904
8905 final int N = mWindows.size();
8906 int i;
8907
Joe Onorato8a9b2202010-02-26 18:56:32 -08008908 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008909 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
8910
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008911 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07008912
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008913 int seq = mLayoutSeq+1;
8914 if (seq < 0) seq = 0;
8915 mLayoutSeq = seq;
8916
8917 // First perform layout of any root windows (not attached
8918 // to another window).
8919 int topAttached = -1;
8920 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008921 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008922
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008923 // Don't do layout of a window if it is not visible, or
8924 // soon won't be visible, to avoid wasting time and funky
8925 // changes while a window is animating away.
8926 final AppWindowToken atoken = win.mAppToken;
8927 final boolean gone = win.mViewVisibility == View.GONE
8928 || !win.mRelayoutCalled
8929 || win.mRootToken.hidden
8930 || (atoken != null && atoken.hiddenRequested)
8931 || win.mAttachedHidden
8932 || win.mExiting || win.mDestroying;
8933
8934 if (!win.mLayoutAttached) {
8935 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
8936 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8937 + " mLayoutAttached=" + win.mLayoutAttached);
8938 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
8939 + win.mViewVisibility + " mRelayoutCalled="
8940 + win.mRelayoutCalled + " hidden="
8941 + win.mRootToken.hidden + " hiddenRequested="
8942 + (atoken != null && atoken.hiddenRequested)
8943 + " mAttachedHidden=" + win.mAttachedHidden);
8944 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008945
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008946 // If this view is GONE, then skip it -- keep the current
8947 // frame, and let the caller know so they can ignore it
8948 // if they want. (We do the normal layout for INVISIBLE
8949 // windows, since that means "perform layout as normal,
8950 // just don't display").
8951 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008952 if (!win.mLayoutAttached) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008953 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8954 win.mLayoutSeq = seq;
8955 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8956 + win.mFrame + " mContainingFrame="
8957 + win.mContainingFrame + " mDisplayFrame="
8958 + win.mDisplayFrame);
8959 } else {
8960 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008961 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008963 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008964
8965 // Now perform layout of attached windows, which usually
8966 // depend on the position of the window they are attached to.
8967 // XXX does not deal with windows that are attached to windows
8968 // that are themselves attached.
8969 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008970 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008971
8972 // If this view is GONE, then skip it -- keep the current
8973 // frame, and let the caller know so they can ignore it
8974 // if they want. (We do the normal layout for INVISIBLE
8975 // windows, since that means "perform layout as normal,
8976 // just don't display").
8977 if (win.mLayoutAttached) {
8978 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
8979 + " mHaveFrame=" + win.mHaveFrame
8980 + " mViewVisibility=" + win.mViewVisibility
8981 + " mRelayoutCalled=" + win.mRelayoutCalled);
8982 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
8983 || !win.mHaveFrame) {
8984 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8985 win.mLayoutSeq = seq;
8986 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
8987 + win.mFrame + " mContainingFrame="
8988 + win.mContainingFrame + " mDisplayFrame="
8989 + win.mDisplayFrame);
8990 }
8991 }
8992 }
Jeff Brown349703e2010-06-22 01:27:15 -07008993
8994 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008995 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008996
8997 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 }
Romain Guy06882f82009-06-10 13:36:04 -07008999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000 private final void performLayoutAndPlaceSurfacesLockedInner(
9001 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009002 if (mDisplay == null) {
9003 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9004 return;
9005 }
9006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 final long currentTime = SystemClock.uptimeMillis();
9008 final int dw = mDisplay.getWidth();
9009 final int dh = mDisplay.getHeight();
9010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 int i;
9012
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009013 if (mFocusMayChange) {
9014 mFocusMayChange = false;
9015 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9016 }
9017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009018 // Initialize state of exiting tokens.
9019 for (i=mExitingTokens.size()-1; i>=0; i--) {
9020 mExitingTokens.get(i).hasVisible = false;
9021 }
9022
9023 // Initialize state of exiting applications.
9024 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9025 mExitingAppTokens.get(i).hasVisible = false;
9026 }
9027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 boolean orientationChangeComplete = true;
9029 Session holdScreen = null;
9030 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009031 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009032 boolean focusDisplayed = false;
9033 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009034 boolean createWatermark = false;
9035
9036 if (mFxSession == null) {
9037 mFxSession = new SurfaceSession();
9038 createWatermark = true;
9039 }
9040
9041 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042
9043 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009044
9045 if (createWatermark) {
9046 createWatermark();
9047 }
9048 if (mWatermark != null) {
9049 mWatermark.positionSurface(dw, dh);
9050 }
9051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009053 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009054 int repeats = 0;
9055 int changes = 0;
9056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009057 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009058 repeats++;
9059 if (repeats > 6) {
9060 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9061 mLayoutNeeded = false;
9062 break;
9063 }
9064
9065 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9066 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9067 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9068 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9069 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9070 assignLayersLocked();
9071 mLayoutNeeded = true;
9072 }
9073 }
9074 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9075 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9076 if (updateOrientationFromAppTokensLocked()) {
9077 mLayoutNeeded = true;
9078 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9079 }
9080 }
9081 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9082 mLayoutNeeded = true;
9083 }
9084 }
9085
9086 // FIRST LOOP: Perform a layout, if needed.
9087 if (repeats < 4) {
9088 changes = performLayoutLockedInner();
9089 if (changes != 0) {
9090 continue;
9091 }
9092 } else {
9093 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9094 changes = 0;
9095 }
9096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009097 final int transactionSequence = ++mTransactionSequence;
9098
9099 // Update animations of all applications, including those
9100 // associated with exiting/removed apps
9101 boolean tokensAnimating = false;
9102 final int NAT = mAppTokens.size();
9103 for (i=0; i<NAT; i++) {
9104 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9105 tokensAnimating = true;
9106 }
9107 }
9108 final int NEAT = mExitingAppTokens.size();
9109 for (i=0; i<NEAT; i++) {
9110 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9111 tokensAnimating = true;
9112 }
9113 }
9114
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009115 // SECOND LOOP: Execute animations and update visibility of windows.
9116
Joe Onorato8a9b2202010-02-26 18:56:32 -08009117 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009118 + transactionSequence + " tokensAnimating="
9119 + tokensAnimating);
9120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009121 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009122
9123 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009124 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009125 boolean forceHiding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126
9127 mPolicy.beginAnimationLw(dw, dh);
9128
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009129 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009131 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009132 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009133
9134 final WindowManager.LayoutParams attrs = w.mAttrs;
9135
9136 if (w.mSurface != null) {
9137 // Execute animation.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009138 if (w.commitFinishDrawingLocked(currentTime)) {
9139 if ((w.mAttrs.flags
9140 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009141 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009142 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009143 wallpaperMayChange = true;
9144 }
9145 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009146
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009147 boolean wasAnimating = w.mAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148 if (w.stepAnimationLocked(currentTime, dw, dh)) {
9149 animating = true;
9150 //w.dump(" ");
9151 }
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009152 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9153 wallpaperMayChange = true;
9154 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009155
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009156 if (mPolicy.doesForceHide(w, attrs)) {
9157 if (!wasAnimating && animating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009158 if (DEBUG_VISIBILITY) Slog.v(TAG,
9159 "Animation done that could impact force hide: "
9160 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009161 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009162 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009163 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9164 forceHiding = true;
9165 }
9166 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9167 boolean changed;
9168 if (forceHiding) {
9169 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009170 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9171 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009172 } else {
9173 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009174 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9175 "Now policy shown: " + w);
9176 if (changed) {
9177 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009178 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009179 // Assume we will need to animate. If
9180 // we don't (because the wallpaper will
9181 // stay with the lock screen), then we will
9182 // clean up later.
9183 Animation a = mPolicy.createForceHideEnterAnimation();
9184 if (a != null) {
9185 w.setAnimation(a);
9186 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009187 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009188 if (mCurrentFocus == null ||
9189 mCurrentFocus.mLayer < w.mLayer) {
9190 // We are showing on to of the current
9191 // focus, so re-evaluate focus to make
9192 // sure it is correct.
9193 mFocusMayChange = true;
9194 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009195 }
9196 }
9197 if (changed && (attrs.flags
9198 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9199 wallpaperMayChange = true;
9200 }
9201 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009203 mPolicy.animatingWindowLw(w, attrs);
9204 }
9205
9206 final AppWindowToken atoken = w.mAppToken;
9207 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9208 if (atoken.lastTransactionSequence != transactionSequence) {
9209 atoken.lastTransactionSequence = transactionSequence;
9210 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9211 atoken.startingDisplayed = false;
9212 }
9213 if ((w.isOnScreen() || w.mAttrs.type
9214 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9215 && !w.mExiting && !w.mDestroying) {
9216 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009217 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009218 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009219 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009220 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009221 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 + " pv=" + w.mPolicyVisibility
9223 + " dp=" + w.mDrawPending
9224 + " cdp=" + w.mCommitDrawPending
9225 + " ah=" + w.mAttachedHidden
9226 + " th=" + atoken.hiddenRequested
9227 + " a=" + w.mAnimating);
9228 }
9229 }
9230 if (w != atoken.startingWindow) {
9231 if (!atoken.freezingScreen || !w.mAppFreezing) {
9232 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009233 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009235 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 "tokenMayBeDrawn: " + atoken
9237 + " freezingScreen=" + atoken.freezingScreen
9238 + " mAppFreezing=" + w.mAppFreezing);
9239 tokenMayBeDrawn = true;
9240 }
9241 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009242 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009243 atoken.startingDisplayed = true;
9244 }
9245 }
9246 } else if (w.mReadyToShow) {
9247 w.performShowLocked();
9248 }
9249 }
9250
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009251 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252
9253 if (tokenMayBeDrawn) {
9254 // See if any windows have been drawn, so they (and others
9255 // associated with them) can now be shown.
9256 final int NT = mTokenList.size();
9257 for (i=0; i<NT; i++) {
9258 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9259 if (wtoken == null) {
9260 continue;
9261 }
9262 if (wtoken.freezingScreen) {
9263 int numInteresting = wtoken.numInterestingWindows;
9264 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009265 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009266 "allDrawn: " + wtoken
9267 + " interesting=" + numInteresting
9268 + " drawn=" + wtoken.numDrawnWindows);
9269 wtoken.showAllWindowsLocked();
9270 unsetAppFreezingScreenLocked(wtoken, false, true);
9271 orientationChangeComplete = true;
9272 }
9273 } else if (!wtoken.allDrawn) {
9274 int numInteresting = wtoken.numInterestingWindows;
9275 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009276 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 "allDrawn: " + wtoken
9278 + " interesting=" + numInteresting
9279 + " drawn=" + wtoken.numDrawnWindows);
9280 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009281 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282
9283 // We can now show all of the drawn windows!
9284 if (!mOpeningApps.contains(wtoken)) {
9285 wtoken.showAllWindowsLocked();
9286 }
9287 }
9288 }
9289 }
9290 }
9291
9292 // If we are ready to perform an app transition, check through
9293 // all of the app tokens to be shown and see if they are ready
9294 // to go.
9295 if (mAppTransitionReady) {
9296 int NN = mOpeningApps.size();
9297 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009298 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299 "Checking " + NN + " opening apps (frozen="
9300 + mDisplayFrozen + " timeout="
9301 + mAppTransitionTimeout + ")...");
9302 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9303 // If the display isn't frozen, wait to do anything until
9304 // all of the apps are ready. Otherwise just go because
9305 // we'll unfreeze the display when everyone is ready.
9306 for (i=0; i<NN && goodToGo; i++) {
9307 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009308 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 "Check opening app" + wtoken + ": allDrawn="
9310 + wtoken.allDrawn + " startingDisplayed="
9311 + wtoken.startingDisplayed);
9312 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9313 && !wtoken.startingMoved) {
9314 goodToGo = false;
9315 }
9316 }
9317 }
9318 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009319 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009320 int transit = mNextAppTransition;
9321 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009322 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009323 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009324 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009326 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327 mAppTransitionTimeout = false;
9328 mStartingIconInTransition = false;
9329 mSkipAppTransitionAnimation = false;
9330
9331 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9332
Dianne Hackborna8f60182009-09-01 19:01:50 -07009333 // If there are applications waiting to come to the
9334 // top of the stack, now is the time to move their windows.
9335 // (Note that we don't do apps going to the bottom
9336 // here -- we want to keep their windows in the old
9337 // Z-order until the animation completes.)
9338 if (mToTopApps.size() > 0) {
9339 NN = mAppTokens.size();
9340 for (i=0; i<NN; i++) {
9341 AppWindowToken wtoken = mAppTokens.get(i);
9342 if (wtoken.sendingToTop) {
9343 wtoken.sendingToTop = false;
9344 moveAppWindowsLocked(wtoken, NN, false);
9345 }
9346 }
9347 mToTopApps.clear();
9348 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009349
Dianne Hackborn25994b42009-09-04 14:21:19 -07009350 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009351
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009352 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009353 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009354
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009355 // The top-most window will supply the layout params,
9356 // and we will determine it below.
9357 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009358 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009359 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009360
Joe Onorato8a9b2202010-02-26 18:56:32 -08009361 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009362 "New wallpaper target=" + mWallpaperTarget
9363 + ", lower target=" + mLowerWallpaperTarget
9364 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009365 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009366 // Do a first pass through the tokens for two
9367 // things:
9368 // (1) Determine if both the closing and opening
9369 // app token sets are wallpaper targets, in which
9370 // case special animations are needed
9371 // (since the wallpaper needs to stay static
9372 // behind them).
9373 // (2) Find the layout params of the top-most
9374 // application window in the tokens, which is
9375 // what will control the animation theme.
9376 final int NC = mClosingApps.size();
9377 NN = NC + mOpeningApps.size();
9378 for (i=0; i<NN; i++) {
9379 AppWindowToken wtoken;
9380 int mode;
9381 if (i < NC) {
9382 wtoken = mClosingApps.get(i);
9383 mode = 1;
9384 } else {
9385 wtoken = mOpeningApps.get(i-NC);
9386 mode = 2;
9387 }
9388 if (mLowerWallpaperTarget != null) {
9389 if (mLowerWallpaperTarget.mAppToken == wtoken
9390 || mUpperWallpaperTarget.mAppToken == wtoken) {
9391 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009392 }
9393 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009394 if (wtoken.appFullscreen) {
9395 WindowState ws = wtoken.findMainWindow();
9396 if (ws != null) {
9397 // If this is a compatibility mode
9398 // window, we will always use its anim.
9399 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9400 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009401 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009402 bestAnimLayer = Integer.MAX_VALUE;
9403 } else if (ws.mLayer > bestAnimLayer) {
9404 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009405 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009406 bestAnimLayer = ws.mLayer;
9407 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009408 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009409 }
9410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009411
Dianne Hackborn25994b42009-09-04 14:21:19 -07009412 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009413 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009414 "Wallpaper animation!");
9415 switch (transit) {
9416 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9417 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9418 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9419 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9420 break;
9421 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9422 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9423 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9424 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9425 break;
9426 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009427 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009428 "New transit: " + transit);
9429 } else if (oldWallpaper != null) {
9430 // We are transitioning from an activity with
9431 // a wallpaper to one without.
9432 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009433 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009434 "New transit away from wallpaper: " + transit);
9435 } else if (mWallpaperTarget != null) {
9436 // We are transitioning from an activity without
9437 // a wallpaper to now showing the wallpaper
9438 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009439 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009440 "New transit into wallpaper: " + transit);
9441 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009442
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009443 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9444 mLastEnterAnimToken = animToken;
9445 mLastEnterAnimParams = animLp;
9446 } else if (mLastEnterAnimParams != null) {
9447 animLp = mLastEnterAnimParams;
9448 mLastEnterAnimToken = null;
9449 mLastEnterAnimParams = null;
9450 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009451
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009452 // If all closing windows are obscured, then there is
9453 // no need to do an animation. This is the case, for
9454 // example, when this transition is being done behind
9455 // the lock screen.
9456 if (!mPolicy.allowAppAnimationsLw()) {
9457 animLp = null;
9458 }
9459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009460 NN = mOpeningApps.size();
9461 for (i=0; i<NN; i++) {
9462 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009463 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009464 "Now opening app" + wtoken);
9465 wtoken.reportedVisible = false;
9466 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009467 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009468 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009470 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471 wtoken.showAllWindowsLocked();
9472 }
9473 NN = mClosingApps.size();
9474 for (i=0; i<NN; i++) {
9475 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009476 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477 "Now closing app" + wtoken);
9478 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009479 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009480 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009481 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009482 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009483 // Force the allDrawn flag, because we want to start
9484 // this guy's animations regardless of whether it's
9485 // gotten drawn.
9486 wtoken.allDrawn = true;
9487 }
9488
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009489 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 mOpeningApps.clear();
9492 mClosingApps.clear();
9493
9494 // This has changed the visibility of windows, so perform
9495 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009496 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009498 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9499 assignLayersLocked();
9500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009501 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009502 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 }
9504 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009505
Dianne Hackborn16064f92010-03-25 00:47:24 -07009506 int adjResult = 0;
9507
Dianne Hackborna8f60182009-09-01 19:01:50 -07009508 if (!animating && mAppTransitionRunning) {
9509 // We have finished the animation of an app transition. To do
9510 // this, we have delayed a lot of operations like showing and
9511 // hiding apps, moving apps in Z-order, etc. The app token list
9512 // reflects the correct Z-order, but the window list may now
9513 // be out of sync with it. So here we will just rebuild the
9514 // entire app window list. Fun!
9515 mAppTransitionRunning = false;
9516 // Clear information about apps that were moving.
9517 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009518
Dianne Hackborna8f60182009-09-01 19:01:50 -07009519 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009520 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009521 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009522 moveInputMethodWindowsIfNeededLocked(false);
9523 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009524 // Since the window list has been rebuilt, focus might
9525 // have to be recomputed since the actual order of windows
9526 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009527 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009528 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009529
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009530 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009531 // At this point, there was a window with a wallpaper that
9532 // was force hiding other windows behind it, but now it
9533 // is going away. This may be simple -- just animate
9534 // away the wallpaper and its window -- or it may be
9535 // hard -- the wallpaper now needs to be shown behind
9536 // something that was hidden.
9537 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009538 if (mLowerWallpaperTarget != null
9539 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009540 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009541 "wallpaperForceHiding changed with lower="
9542 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009543 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009544 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
9545 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
9546 if (mLowerWallpaperTarget.mAppToken.hidden) {
9547 // The lower target has become hidden before we
9548 // actually started the animation... let's completely
9549 // re-evaluate everything.
9550 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009551 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009552 }
9553 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07009554 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009555 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009556 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009557 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009558 + " NEW: " + mWallpaperTarget
9559 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009560 if (mLowerWallpaperTarget == null) {
9561 // Whoops, we don't need a special wallpaper animation.
9562 // Clear them out.
9563 forceHiding = false;
9564 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009565 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009566 if (w.mSurface != null) {
9567 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07009568 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009569 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009570 forceHiding = true;
9571 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9572 if (!w.mAnimating) {
9573 // We set the animation above so it
9574 // is not yet running.
9575 w.clearAnimation();
9576 }
9577 }
9578 }
9579 }
9580 }
9581 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009582
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009583 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009584 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009585 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07009586 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009587 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009588
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009589 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009590 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009591 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009592 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009593 assignLayersLocked();
9594 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009595 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009596 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009597 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009599
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009600 if (mFocusMayChange) {
9601 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009602 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009603 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009604 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009605 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009606 }
9607
9608 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009609 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009610 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009611
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009612 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
9613 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009614
Jeff Browne33348b2010-07-15 23:54:05 -07009615 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009616 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009617
9618 // THIRD LOOP: Update the surfaces of all windows.
9619
9620 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9621
9622 boolean obscured = false;
9623 boolean blurring = false;
9624 boolean dimming = false;
9625 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009626 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009627 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009628
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009629 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009631 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009632 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633
9634 boolean displayed = false;
9635 final WindowManager.LayoutParams attrs = w.mAttrs;
9636 final int attrFlags = attrs.flags;
9637
9638 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009639 // XXX NOTE: The logic here could be improved. We have
9640 // the decision about whether to resize a window separated
9641 // from whether to hide the surface. This can cause us to
9642 // resize a surface even if we are going to hide it. You
9643 // can see this by (1) holding device in landscape mode on
9644 // home screen; (2) tapping browser icon (device will rotate
9645 // to landscape; (3) tap home. The wallpaper will be resized
9646 // in step 2 but then immediately hidden, causing us to
9647 // have to resize and then redraw it again in step 3. It
9648 // would be nice to figure out how to avoid this, but it is
9649 // difficult because we do need to resize surfaces in some
9650 // cases while they are hidden such as when first showing a
9651 // window.
9652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009653 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009654 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009655 TAG, "Placing surface #" + i + " " + w.mSurface
9656 + ": new=" + w.mShownFrame + ", old="
9657 + w.mLastShownFrame);
9658
9659 boolean resize;
9660 int width, height;
9661 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9662 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9663 w.mLastRequestedHeight != w.mRequestedHeight;
9664 // for a scaled surface, we just want to use
9665 // the requested size.
9666 width = w.mRequestedWidth;
9667 height = w.mRequestedHeight;
9668 w.mLastRequestedWidth = width;
9669 w.mLastRequestedHeight = height;
9670 w.mLastShownFrame.set(w.mShownFrame);
9671 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009672 if (SHOW_TRANSACTIONS) logSurface(w,
9673 "POS " + w.mShownFrame.left
9674 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009675 w.mSurfaceX = w.mShownFrame.left;
9676 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009677 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9678 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009679 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009680 if (!recoveringMemory) {
9681 reclaimSomeSurfaceMemoryLocked(w, "position");
9682 }
9683 }
9684 } else {
9685 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9686 width = w.mShownFrame.width();
9687 height = w.mShownFrame.height();
9688 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009689 }
9690
9691 if (resize) {
9692 if (width < 1) width = 1;
9693 if (height < 1) height = 1;
9694 if (w.mSurface != null) {
9695 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009696 if (SHOW_TRANSACTIONS) logSurface(w,
9697 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009698 + w.mShownFrame.top + " SIZE "
9699 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009700 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009701 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009702 w.mSurfaceW = width;
9703 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009705 w.mSurfaceX = w.mShownFrame.left;
9706 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009707 w.mSurface.setPosition(w.mShownFrame.left,
9708 w.mShownFrame.top);
9709 } catch (RuntimeException e) {
9710 // If something goes wrong with the surface (such
9711 // as running out of memory), don't take down the
9712 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009713 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009714 + "size=(" + width + "x" + height
9715 + "), pos=(" + w.mShownFrame.left
9716 + "," + w.mShownFrame.top + ")", e);
9717 if (!recoveringMemory) {
9718 reclaimSomeSurfaceMemoryLocked(w, "size");
9719 }
9720 }
9721 }
9722 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009723 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009724 w.mContentInsetsChanged =
9725 !w.mLastContentInsets.equals(w.mContentInsets);
9726 w.mVisibleInsetsChanged =
9727 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009728 boolean configChanged =
9729 w.mConfiguration != mCurConfiguration
9730 && (w.mConfiguration == null
9731 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009732 if (DEBUG_CONFIGURATION && configChanged) {
9733 Slog.v(TAG, "Win " + w + " config changed: "
9734 + mCurConfiguration);
9735 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009736 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009737 + ": configChanged=" + configChanged
9738 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -07009739 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009740 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009741 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009742 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009743 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 w.mLastFrame.set(w.mFrame);
9745 w.mLastContentInsets.set(w.mContentInsets);
9746 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009747 // If the screen is currently frozen, then keep
9748 // it frozen until this window draws at its new
9749 // orientation.
9750 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009751 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009752 "Resizing while display frozen: " + w);
9753 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009754 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009755 mWindowsFreezingScreen = true;
9756 // XXX should probably keep timeout from
9757 // when we first froze the display.
9758 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9759 mH.sendMessageDelayed(mH.obtainMessage(
9760 H.WINDOW_FREEZE_TIMEOUT), 2000);
9761 }
9762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009763 // If the orientation is changing, then we need to
9764 // hold off on unfreezing the display until this
9765 // window has been redrawn; to do that, we need
9766 // to go through the process of getting informed
9767 // by the application when it has finished drawing.
9768 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009769 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009770 "Orientation start waiting for draw in "
9771 + w + ", surface " + w.mSurface);
9772 w.mDrawPending = true;
9773 w.mCommitDrawPending = false;
9774 w.mReadyToShow = false;
9775 if (w.mAppToken != null) {
9776 w.mAppToken.allDrawn = false;
9777 }
9778 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009779 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009780 "Resizing window " + w + " to " + w.mFrame);
9781 mResizingWindows.add(w);
9782 } else if (w.mOrientationChanging) {
9783 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009784 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009785 "Orientation not waiting for draw in "
9786 + w + ", surface " + w.mSurface);
9787 w.mOrientationChanging = false;
9788 }
9789 }
9790 }
9791
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009792 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 if (!w.mLastHidden) {
9794 //dump();
9795 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009796 if (SHOW_TRANSACTIONS) logSurface(w,
9797 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009799 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009800 try {
9801 w.mSurface.hide();
9802 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009803 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009804 }
9805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806 }
9807 // If we are waiting for this window to handle an
9808 // orientation change, well, it is hidden, so
9809 // doesn't really matter. Note that this does
9810 // introduce a potential glitch if the window
9811 // becomes unhidden before it has drawn for the
9812 // new orientation.
9813 if (w.mOrientationChanging) {
9814 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009815 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 "Orientation change skips hidden " + w);
9817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009818 } else if (w.mLastLayer != w.mAnimLayer
9819 || w.mLastAlpha != w.mShownAlpha
9820 || w.mLastDsDx != w.mDsDx
9821 || w.mLastDtDx != w.mDtDx
9822 || w.mLastDsDy != w.mDsDy
9823 || w.mLastDtDy != w.mDtDy
9824 || w.mLastHScale != w.mHScale
9825 || w.mLastVScale != w.mVScale
9826 || w.mLastHidden) {
9827 displayed = true;
9828 w.mLastAlpha = w.mShownAlpha;
9829 w.mLastLayer = w.mAnimLayer;
9830 w.mLastDsDx = w.mDsDx;
9831 w.mLastDtDx = w.mDtDx;
9832 w.mLastDsDy = w.mDsDy;
9833 w.mLastDtDy = w.mDtDy;
9834 w.mLastHScale = w.mHScale;
9835 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009836 if (SHOW_TRANSACTIONS) logSurface(w,
9837 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009838 + " matrix=[" + (w.mDsDx*w.mHScale)
9839 + "," + (w.mDtDx*w.mVScale)
9840 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009841 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 if (w.mSurface != null) {
9843 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07009844 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009846 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009847 w.mSurface.setLayer(w.mAnimLayer);
9848 w.mSurface.setMatrix(
9849 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
9850 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
9851 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009852 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 if (!recoveringMemory) {
9854 reclaimSomeSurfaceMemoryLocked(w, "update");
9855 }
9856 }
9857 }
9858
9859 if (w.mLastHidden && !w.mDrawPending
9860 && !w.mCommitDrawPending
9861 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009862 if (SHOW_TRANSACTIONS) logSurface(w,
9863 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009864 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009865 + " during relayout");
9866 if (showSurfaceRobustlyLocked(w)) {
9867 w.mHasDrawn = true;
9868 w.mLastHidden = false;
9869 } else {
9870 w.mOrientationChanging = false;
9871 }
9872 }
9873 if (w.mSurface != null) {
9874 w.mToken.hasVisible = true;
9875 }
9876 } else {
9877 displayed = true;
9878 }
9879
9880 if (displayed) {
9881 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08009882 if (attrs.width == LayoutParams.MATCH_PARENT
9883 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009884 covered = true;
9885 }
9886 }
9887 if (w.mOrientationChanging) {
9888 if (w.mDrawPending || w.mCommitDrawPending) {
9889 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009890 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 "Orientation continue waiting for draw in " + w);
9892 } else {
9893 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009894 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 "Orientation change complete in " + w);
9896 }
9897 }
9898 w.mToken.hasVisible = true;
9899 }
9900 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009901 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009902 "Orientation change skips hidden " + w);
9903 w.mOrientationChanging = false;
9904 }
9905
9906 final boolean canBeSeen = w.isDisplayedLw();
9907
9908 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
9909 focusDisplayed = true;
9910 }
9911
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07009912 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009914 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009915 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 if (w.mSurface != null) {
9917 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
9918 holdScreen = w.mSession;
9919 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009920 if (!syswin && w.mAttrs.screenBrightness >= 0
9921 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009922 screenBrightness = w.mAttrs.screenBrightness;
9923 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009924 if (!syswin && w.mAttrs.buttonBrightness >= 0
9925 && buttonBrightness < 0) {
9926 buttonBrightness = w.mAttrs.buttonBrightness;
9927 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05009928 if (canBeSeen
9929 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
9930 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
9931 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009932 syswin = true;
9933 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009935
Dianne Hackborn25994b42009-09-04 14:21:19 -07009936 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
9937 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 // This window completely covers everything behind it,
9939 // so we want to leave all of them as unblurred (for
9940 // performance reasons).
9941 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009942 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009943 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009944 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009945 obscured = true;
9946 if (mBackgroundFillerSurface == null) {
9947 try {
9948 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009949 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009950 0, dw, dh,
9951 PixelFormat.OPAQUE,
9952 Surface.FX_SURFACE_NORMAL);
9953 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009954 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009955 }
9956 }
9957 try {
9958 mBackgroundFillerSurface.setPosition(0, 0);
9959 mBackgroundFillerSurface.setSize(dw, dh);
9960 // Using the same layer as Dim because they will never be shown at the
9961 // same time.
9962 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
9963 mBackgroundFillerSurface.show();
9964 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009965 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009966 }
9967 backgroundFillerShown = true;
9968 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009969 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009971 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009972 + ": blurring=" + blurring
9973 + " obscured=" + obscured
9974 + " displayed=" + displayed);
9975 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
9976 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009977 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009979 if (mDimAnimator == null) {
9980 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009982 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009983 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009985 }
9986 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
9987 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009988 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009989 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009991 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 + mBlurSurface + ": CREATE");
9993 try {
Romain Guy06882f82009-06-10 13:36:04 -07009994 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08009995 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 -1, 16, 16,
9997 PixelFormat.OPAQUE,
9998 Surface.FX_SURFACE_BLUR);
9999 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010000 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010001 }
10002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010004 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10005 + mBlurSurface + ": pos=(0,0) (" +
10006 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010007 mBlurSurface.setPosition(0, 0);
10008 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010009 mBlurSurface.setLayer(w.mAnimLayer-2);
10010 if (!mBlurShown) {
10011 try {
10012 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10013 + mBlurSurface + ": SHOW");
10014 mBlurSurface.show();
10015 } catch (RuntimeException e) {
10016 Slog.w(TAG, "Failure showing blur surface", e);
10017 }
10018 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019 }
10020 }
10021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 }
10023 }
10024 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010025
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010026 if (obscuredChanged && mWallpaperTarget == w) {
10027 // This is the wallpaper target and its obscured state
10028 // changed... make sure the current wallaper's visibility
10029 // has been updated accordingly.
10030 updateWallpaperVisibilityLocked();
10031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010032 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010033
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010034 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10035 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010036 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010037 try {
10038 mBackgroundFillerSurface.hide();
10039 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010040 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010041 }
10042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010044 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010045 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10046 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010047 }
Romain Guy06882f82009-06-10 13:36:04 -070010048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010050 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 + ": HIDE");
10052 try {
10053 mBlurSurface.hide();
10054 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010055 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010056 }
10057 mBlurShown = false;
10058 }
10059
Joe Onorato8a9b2202010-02-26 18:56:32 -080010060 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010062 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 }
10064
Jeff Browne33348b2010-07-15 23:54:05 -070010065 mInputMonitor.updateInputWindowsLw();
10066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010068
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010069 if (mWatermark != null) {
10070 mWatermark.drawIfNeeded();
10071 }
10072
Joe Onorato8a9b2202010-02-26 18:56:32 -080010073 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010074 "With display frozen, orientationChangeComplete="
10075 + orientationChangeComplete);
10076 if (orientationChangeComplete) {
10077 if (mWindowsFreezingScreen) {
10078 mWindowsFreezingScreen = false;
10079 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10080 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010081 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010082 }
Romain Guy06882f82009-06-10 13:36:04 -070010083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 i = mResizingWindows.size();
10085 if (i > 0) {
10086 do {
10087 i--;
10088 WindowState win = mResizingWindows.get(i);
10089 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010090 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10091 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010092 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010093 boolean configChanged =
10094 win.mConfiguration != mCurConfiguration
10095 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010096 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10097 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10098 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010099 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010100 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010101 + " / " + mCurConfiguration + " / 0x"
10102 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010103 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010104 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 win.mClient.resized(win.mFrame.width(),
10106 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010107 win.mLastVisibleInsets, win.mDrawPending,
10108 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109 win.mContentInsetsChanged = false;
10110 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010111 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 } catch (RemoteException e) {
10113 win.mOrientationChanging = false;
10114 }
10115 } while (i > 0);
10116 mResizingWindows.clear();
10117 }
Romain Guy06882f82009-06-10 13:36:04 -070010118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010119 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010120 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 i = mDestroySurface.size();
10122 if (i > 0) {
10123 do {
10124 i--;
10125 WindowState win = mDestroySurface.get(i);
10126 win.mDestroying = false;
10127 if (mInputMethodWindow == win) {
10128 mInputMethodWindow = null;
10129 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010130 if (win == mWallpaperTarget) {
10131 wallpaperDestroyed = true;
10132 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 win.destroySurfaceLocked();
10134 } while (i > 0);
10135 mDestroySurface.clear();
10136 }
10137
10138 // Time to remove any exiting tokens?
10139 for (i=mExitingTokens.size()-1; i>=0; i--) {
10140 WindowToken token = mExitingTokens.get(i);
10141 if (!token.hasVisible) {
10142 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010143 if (token.windowType == TYPE_WALLPAPER) {
10144 mWallpaperTokens.remove(token);
10145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 }
10147 }
10148
10149 // Time to remove any exiting applications?
10150 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10151 AppWindowToken token = mExitingAppTokens.get(i);
10152 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010153 // Make sure there is no animation running on this token,
10154 // so any windows associated with it will be removed as
10155 // soon as their animations are complete
10156 token.animation = null;
10157 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 mAppTokens.remove(token);
10159 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010160 if (mLastEnterAnimToken == token) {
10161 mLastEnterAnimToken = null;
10162 mLastEnterAnimParams = null;
10163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010164 }
10165 }
10166
Dianne Hackborna8f60182009-09-01 19:01:50 -070010167 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010168
Dianne Hackborna8f60182009-09-01 19:01:50 -070010169 if (!animating && mAppTransitionRunning) {
10170 // We have finished the animation of an app transition. To do
10171 // this, we have delayed a lot of operations like showing and
10172 // hiding apps, moving apps in Z-order, etc. The app token list
10173 // reflects the correct Z-order, but the window list may now
10174 // be out of sync with it. So here we will just rebuild the
10175 // entire app window list. Fun!
10176 mAppTransitionRunning = false;
10177 needRelayout = true;
10178 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010179 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010180 // Clear information about apps that were moving.
10181 mToBottomApps.clear();
10182 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 if (focusDisplayed) {
10185 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10186 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010187 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010188 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010189 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010190 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010191 requestAnimationLocked(0);
10192 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10194 }
Jeff Browneb857f12010-07-16 10:06:33 -070010195
Jeff Browne33348b2010-07-15 23:54:05 -070010196 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010197
Jeff Brown8e03b752010-06-13 19:16:55 -070010198 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10200 mPowerManager.setScreenBrightnessOverride(-1);
10201 } else {
10202 mPowerManager.setScreenBrightnessOverride((int)
10203 (screenBrightness * Power.BRIGHTNESS_ON));
10204 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010205 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10206 mPowerManager.setButtonBrightnessOverride(-1);
10207 } else {
10208 mPowerManager.setButtonBrightnessOverride((int)
10209 (buttonBrightness * Power.BRIGHTNESS_ON));
10210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010211 if (holdScreen != mHoldingScreenOn) {
10212 mHoldingScreenOn = holdScreen;
10213 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10214 mH.sendMessage(m);
10215 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010216
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010217 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010218 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010219 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10220 LocalPowerManager.BUTTON_EVENT, true);
10221 mTurnOnScreen = false;
10222 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010223
10224 // Check to see if we are now in a state where the screen should
10225 // be enabled, because the window obscured flags have changed.
10226 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010227 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010228
10229 /**
10230 * Must be called with the main window manager lock held.
10231 */
10232 void setHoldScreenLocked(boolean holding) {
10233 boolean state = mHoldingScreenWakeLock.isHeld();
10234 if (holding != state) {
10235 if (holding) {
10236 mHoldingScreenWakeLock.acquire();
10237 } else {
10238 mPolicy.screenOnStoppedLw();
10239 mHoldingScreenWakeLock.release();
10240 }
10241 }
10242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243
10244 void requestAnimationLocked(long delay) {
10245 if (!mAnimationPending) {
10246 mAnimationPending = true;
10247 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10248 }
10249 }
Romain Guy06882f82009-06-10 13:36:04 -070010250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010251 /**
10252 * Have the surface flinger show a surface, robustly dealing with
10253 * error conditions. In particular, if there is not enough memory
10254 * to show the surface, then we will try to get rid of other surfaces
10255 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010256 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010257 * @return Returns true if the surface was successfully shown.
10258 */
10259 boolean showSurfaceRobustlyLocked(WindowState win) {
10260 try {
10261 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010262 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010263 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010264 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010265 if (DEBUG_VISIBILITY) Slog.v(TAG,
10266 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010267 win.mTurnOnScreen = false;
10268 mTurnOnScreen = true;
10269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 }
10271 return true;
10272 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010273 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 }
Romain Guy06882f82009-06-10 13:36:04 -070010275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010278 return false;
10279 }
Romain Guy06882f82009-06-10 13:36:04 -070010280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10282 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010283
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010284 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 if (mForceRemoves == null) {
10288 mForceRemoves = new ArrayList<WindowState>();
10289 }
Romain Guy06882f82009-06-10 13:36:04 -070010290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010291 long callingIdentity = Binder.clearCallingIdentity();
10292 try {
10293 // There was some problem... first, do a sanity check of the
10294 // window list to make sure we haven't left any dangling surfaces
10295 // around.
10296 int N = mWindows.size();
10297 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010298 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010300 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 if (ws.mSurface != null) {
10302 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010303 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 + ws + " surface=" + ws.mSurface
10305 + " token=" + win.mToken
10306 + " pid=" + ws.mSession.mPid
10307 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010308 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010309 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010310 ws.mSurface = null;
10311 mForceRemoves.add(ws);
10312 i--;
10313 N--;
10314 leakedSurface = true;
10315 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010316 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010317 + ws + " surface=" + ws.mSurface
10318 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010319 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010320 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 ws.mSurface = null;
10322 leakedSurface = true;
10323 }
10324 }
10325 }
Romain Guy06882f82009-06-10 13:36:04 -070010326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010327 boolean killedApps = false;
10328 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010329 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 SparseIntArray pidCandidates = new SparseIntArray();
10331 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010332 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 if (ws.mSurface != null) {
10334 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10335 }
10336 }
10337 if (pidCandidates.size() > 0) {
10338 int[] pids = new int[pidCandidates.size()];
10339 for (int i=0; i<pids.length; i++) {
10340 pids[i] = pidCandidates.keyAt(i);
10341 }
10342 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010343 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010344 killedApps = true;
10345 }
10346 } catch (RemoteException e) {
10347 }
10348 }
10349 }
Romain Guy06882f82009-06-10 13:36:04 -070010350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010351 if (leakedSurface || killedApps) {
10352 // We managed to reclaim some memory, so get rid of the trouble
10353 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010354 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010355 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010356 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010357 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010358 win.mSurface = null;
10359 }
Romain Guy06882f82009-06-10 13:36:04 -070010360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 try {
10362 win.mClient.dispatchGetNewSurface();
10363 } catch (RemoteException e) {
10364 }
10365 }
10366 } finally {
10367 Binder.restoreCallingIdentity(callingIdentity);
10368 }
10369 }
Romain Guy06882f82009-06-10 13:36:04 -070010370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 private boolean updateFocusedWindowLocked(int mode) {
10372 WindowState newFocus = computeFocusedWindowLocked();
10373 if (mCurrentFocus != newFocus) {
10374 // This check makes sure that we don't already have the focus
10375 // change message pending.
10376 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10377 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010378 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10380 final WindowState oldFocus = mCurrentFocus;
10381 mCurrentFocus = newFocus;
10382 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 final WindowState imWindow = mInputMethodWindow;
10385 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010386 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010387 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010388 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10389 mLayoutNeeded = true;
10390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010391 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
10392 performLayoutLockedInner();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010393 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10394 // Client will do the layout, but we need to assign layers
10395 // for handleNewWindowLocked() below.
10396 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 }
10398 }
Jeff Brown349703e2010-06-22 01:27:15 -070010399
10400 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10401 // If we defer assigning layers, then the caller is responsible for
10402 // doing this part.
10403 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 return true;
10406 }
10407 return false;
10408 }
Jeff Brown349703e2010-06-22 01:27:15 -070010409
10410 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010411 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413
10414 private WindowState computeFocusedWindowLocked() {
10415 WindowState result = null;
10416 WindowState win;
10417
10418 int i = mWindows.size() - 1;
10419 int nextAppIndex = mAppTokens.size()-1;
10420 WindowToken nextApp = nextAppIndex >= 0
10421 ? mAppTokens.get(nextAppIndex) : null;
10422
10423 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010424 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010425
Joe Onorato8a9b2202010-02-26 18:56:32 -080010426 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 TAG, "Looking for focus: " + i
10428 + " = " + win
10429 + ", flags=" + win.mAttrs.flags
10430 + ", canReceive=" + win.canReceiveKeys());
10431
10432 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434 // If this window's application has been removed, just skip it.
10435 if (thisApp != null && thisApp.removed) {
10436 i--;
10437 continue;
10438 }
Romain Guy06882f82009-06-10 13:36:04 -070010439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010440 // If there is a focused app, don't allow focus to go to any
10441 // windows below it. If this is an application window, step
10442 // through the app tokens until we find its app.
10443 if (thisApp != null && nextApp != null && thisApp != nextApp
10444 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10445 int origAppIndex = nextAppIndex;
10446 while (nextAppIndex > 0) {
10447 if (nextApp == mFocusedApp) {
10448 // Whoops, we are below the focused app... no focus
10449 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010450 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 TAG, "Reached focused app: " + mFocusedApp);
10452 return null;
10453 }
10454 nextAppIndex--;
10455 nextApp = mAppTokens.get(nextAppIndex);
10456 if (nextApp == thisApp) {
10457 break;
10458 }
10459 }
10460 if (thisApp != nextApp) {
10461 // Uh oh, the app token doesn't exist! This shouldn't
10462 // happen, but if it does we can get totally hosed...
10463 // so restart at the original app.
10464 nextAppIndex = origAppIndex;
10465 nextApp = mAppTokens.get(nextAppIndex);
10466 }
10467 }
10468
10469 // Dispatch to this window if it is wants key events.
10470 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010471 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010472 TAG, "Found focus @ " + i + " = " + win);
10473 result = win;
10474 break;
10475 }
10476
10477 i--;
10478 }
10479
10480 return result;
10481 }
10482
10483 private void startFreezingDisplayLocked() {
10484 if (mDisplayFrozen) {
10485 return;
10486 }
Romain Guy06882f82009-06-10 13:36:04 -070010487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010488 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010491 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010492 if (mFreezeGcPending != 0) {
10493 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010494 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 mH.removeMessages(H.FORCE_GC);
10496 Runtime.getRuntime().gc();
10497 mFreezeGcPending = now;
10498 }
10499 } else {
10500 mFreezeGcPending = now;
10501 }
Romain Guy06882f82009-06-10 13:36:04 -070010502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010503 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010504
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010505 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010506
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010507 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10508 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010509 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010510 mAppTransitionReady = true;
10511 }
Romain Guy06882f82009-06-10 13:36:04 -070010512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010513 if (PROFILE_ORIENTATION) {
10514 File file = new File("/data/system/frozen");
10515 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10516 }
10517 Surface.freezeDisplay(0);
10518 }
Romain Guy06882f82009-06-10 13:36:04 -070010519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010520 private void stopFreezingDisplayLocked() {
10521 if (!mDisplayFrozen) {
10522 return;
10523 }
Romain Guy06882f82009-06-10 13:36:04 -070010524
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010525 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
10526 return;
10527 }
10528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010529 mDisplayFrozen = false;
10530 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
10531 if (PROFILE_ORIENTATION) {
10532 Debug.stopMethodTracing();
10533 }
10534 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070010535
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010536 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010537
Christopher Tateb696aee2010-04-02 19:08:30 -070010538 // While the display is frozen we don't re-compute the orientation
10539 // to avoid inconsistent states. However, something interesting
10540 // could have actually changed during that time so re-evaluate it
10541 // now to catch that.
10542 if (updateOrientationFromAppTokensLocked()) {
10543 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10544 }
10545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 // A little kludge: a lot could have happened while the
10547 // display was frozen, so now that we are coming back we
10548 // do a gc so that any remote references the system
10549 // processes holds on others can be released if they are
10550 // no longer needed.
10551 mH.removeMessages(H.FORCE_GC);
10552 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10553 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 mScreenFrozenLock.release();
10556 }
Romain Guy06882f82009-06-10 13:36:04 -070010557
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010558 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10559 DisplayMetrics dm) {
10560 if (index < tokens.length) {
10561 String str = tokens[index];
10562 if (str != null && str.length() > 0) {
10563 try {
10564 int val = Integer.parseInt(str);
10565 return val;
10566 } catch (Exception e) {
10567 }
10568 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010569 }
10570 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10571 return defDps;
10572 }
10573 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10574 return val;
10575 }
10576
10577 class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010578 final String[] mTokens;
10579 final String mText;
10580 final Paint mTextPaint;
10581 final int mTextWidth;
10582 final int mTextHeight;
10583 final int mTextAscent;
10584 final int mTextDescent;
10585 final int mDeltaX;
10586 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010587
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010588 Surface mSurface;
10589 int mLastDW;
10590 int mLastDH;
10591 boolean mDrawNeeded;
10592
10593 Watermark(SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010594 final DisplayMetrics dm = new DisplayMetrics();
10595 mDisplay.getMetrics(dm);
10596
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010597 if (false) {
10598 Log.i(TAG, "*********************** WATERMARK");
10599 for (int i=0; i<tokens.length; i++) {
10600 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
10601 }
10602 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010603
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010604 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010605
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010606 StringBuilder builder = new StringBuilder(32);
10607 int len = mTokens[0].length();
10608 len = len & ~1;
10609 for (int i=0; i<len; i+=2) {
10610 int c1 = mTokens[0].charAt(i);
10611 int c2 = mTokens[0].charAt(i+1);
10612 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
10613 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
10614 else c1 -= '0';
10615 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
10616 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
10617 else c2 -= '0';
10618 builder.append((char)(255-((c1*16)+c2)));
10619 }
10620 mText = builder.toString();
10621 if (false) {
10622 Log.i(TAG, "Final text: " + mText);
10623 }
10624
10625 int fontSize = getPropertyInt(tokens, 1,
10626 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
10627
10628 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
10629 mTextPaint.setTextSize(fontSize);
10630 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
10631
10632 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
10633 mTextWidth = (int)mTextPaint.measureText(mText);
10634 mTextAscent = fm.ascent;
10635 mTextDescent = fm.descent;
10636 mTextHeight = fm.descent - fm.ascent;
10637
10638 mDeltaX = getPropertyInt(tokens, 2,
10639 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
10640 mDeltaY = getPropertyInt(tokens, 3,
10641 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
10642 int shadowColor = getPropertyInt(tokens, 4,
10643 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
10644 int color = getPropertyInt(tokens, 5,
10645 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
10646 int shadowRadius = getPropertyInt(tokens, 6,
10647 TypedValue.COMPLEX_UNIT_PX, 7, dm);
10648 int shadowDx = getPropertyInt(tokens, 8,
10649 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10650 int shadowDy = getPropertyInt(tokens, 9,
10651 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10652
10653 mTextPaint.setColor(color);
10654 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010655
10656 try {
10657 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010658 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010659 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010660 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010661 mSurface.show();
10662 } catch (OutOfResourcesException e) {
10663 }
10664 }
10665
10666 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010667 if (mLastDW != dw || mLastDH != dh) {
10668 mLastDW = dw;
10669 mLastDH = dh;
10670 mSurface.setSize(dw, dh);
10671 mDrawNeeded = true;
10672 }
10673 }
10674
10675 void drawIfNeeded() {
10676 if (mDrawNeeded) {
10677 final int dw = mLastDW;
10678 final int dh = mLastDH;
10679
10680 mDrawNeeded = false;
10681 Rect dirty = new Rect(0, 0, dw, dh);
10682 Canvas c = null;
10683 try {
10684 c = mSurface.lockCanvas(dirty);
10685 } catch (IllegalArgumentException e) {
10686 } catch (OutOfResourcesException e) {
10687 }
10688 if (c != null) {
10689 int deltaX = mDeltaX;
10690 int deltaY = mDeltaY;
10691
10692 // deltaX shouldn't be close to a round fraction of our
10693 // x step, or else things will line up too much.
10694 int div = (dw+mTextWidth)/deltaX;
10695 int rem = (dw+mTextWidth) - (div*deltaX);
10696 int qdelta = deltaX/4;
10697 if (rem < qdelta || rem > (deltaX-qdelta)) {
10698 deltaX += deltaX/3;
10699 }
10700
10701 int y = -mTextHeight;
10702 int x = -mTextWidth;
10703 while (y < (dh+mTextHeight)) {
10704 c.drawText(mText, x, y, mTextPaint);
10705 x += deltaX;
10706 if (x >= dw) {
10707 x -= (dw+mTextWidth);
10708 y += deltaY;
10709 }
10710 }
10711 mSurface.unlockCanvasAndPost(c);
10712 }
10713 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010714 }
10715 }
10716
10717 void createWatermark() {
10718 if (mWatermark != null) {
10719 return;
10720 }
10721
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010722 File file = new File("/system/etc/setup.conf");
10723 FileInputStream in = null;
10724 try {
10725 in = new FileInputStream(file);
10726 DataInputStream ind = new DataInputStream(in);
10727 String line = ind.readLine();
10728 if (line != null) {
10729 String[] toks = line.split("%");
10730 if (toks != null && toks.length > 0) {
10731 mWatermark = new Watermark(mFxSession, toks);
10732 }
10733 }
10734 } catch (FileNotFoundException e) {
10735 } catch (IOException e) {
10736 } finally {
10737 if (in != null) {
10738 try {
10739 in.close();
10740 } catch (IOException e) {
10741 }
10742 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010743 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010744 }
10745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010746 @Override
10747 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10748 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10749 != PackageManager.PERMISSION_GRANTED) {
10750 pw.println("Permission Denial: can't dump WindowManager from from pid="
10751 + Binder.getCallingPid()
10752 + ", uid=" + Binder.getCallingUid());
10753 return;
10754 }
Romain Guy06882f82009-06-10 13:36:04 -070010755
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010756 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080010757 pw.println(" ");
10758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010759 synchronized(mWindowMap) {
10760 pw.println("Current Window Manager state:");
10761 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010762 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010763 pw.print(" Window #"); pw.print(i); pw.print(' ');
10764 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 w.dump(pw, " ");
10766 }
10767 if (mInputMethodDialogs.size() > 0) {
10768 pw.println(" ");
10769 pw.println(" Input method dialogs:");
10770 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10771 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010772 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010773 }
10774 }
10775 if (mPendingRemove.size() > 0) {
10776 pw.println(" ");
10777 pw.println(" Remove pending for:");
10778 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10779 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010780 pw.print(" Remove #"); pw.print(i); pw.print(' ');
10781 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 w.dump(pw, " ");
10783 }
10784 }
10785 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10786 pw.println(" ");
10787 pw.println(" Windows force removing:");
10788 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10789 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010790 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10791 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010792 w.dump(pw, " ");
10793 }
10794 }
10795 if (mDestroySurface.size() > 0) {
10796 pw.println(" ");
10797 pw.println(" Windows waiting to destroy their surface:");
10798 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10799 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010800 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
10801 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010802 w.dump(pw, " ");
10803 }
10804 }
10805 if (mLosingFocus.size() > 0) {
10806 pw.println(" ");
10807 pw.println(" Windows losing focus:");
10808 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10809 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010810 pw.print(" Losing #"); pw.print(i); pw.print(' ');
10811 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010812 w.dump(pw, " ");
10813 }
10814 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010815 if (mResizingWindows.size() > 0) {
10816 pw.println(" ");
10817 pw.println(" Windows waiting to resize:");
10818 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10819 WindowState w = mResizingWindows.get(i);
10820 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
10821 pw.print(w); pw.println(":");
10822 w.dump(pw, " ");
10823 }
10824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010825 if (mSessions.size() > 0) {
10826 pw.println(" ");
10827 pw.println(" All active sessions:");
10828 Iterator<Session> it = mSessions.iterator();
10829 while (it.hasNext()) {
10830 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010831 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010832 s.dump(pw, " ");
10833 }
10834 }
10835 if (mTokenMap.size() > 0) {
10836 pw.println(" ");
10837 pw.println(" All tokens:");
10838 Iterator<WindowToken> it = mTokenMap.values().iterator();
10839 while (it.hasNext()) {
10840 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010841 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 token.dump(pw, " ");
10843 }
10844 }
10845 if (mTokenList.size() > 0) {
10846 pw.println(" ");
10847 pw.println(" Window token list:");
10848 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010849 pw.print(" #"); pw.print(i); pw.print(": ");
10850 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 }
10852 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010853 if (mWallpaperTokens.size() > 0) {
10854 pw.println(" ");
10855 pw.println(" Wallpaper tokens:");
10856 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10857 WindowToken token = mWallpaperTokens.get(i);
10858 pw.print(" Wallpaper #"); pw.print(i);
10859 pw.print(' '); pw.print(token); pw.println(':');
10860 token.dump(pw, " ");
10861 }
10862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 if (mAppTokens.size() > 0) {
10864 pw.println(" ");
10865 pw.println(" Application tokens in Z order:");
10866 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010867 pw.print(" App #"); pw.print(i); pw.print(": ");
10868 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010869 }
10870 }
10871 if (mFinishedStarting.size() > 0) {
10872 pw.println(" ");
10873 pw.println(" Finishing start of application tokens:");
10874 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10875 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010876 pw.print(" Finished Starting #"); pw.print(i);
10877 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010878 token.dump(pw, " ");
10879 }
10880 }
10881 if (mExitingTokens.size() > 0) {
10882 pw.println(" ");
10883 pw.println(" Exiting tokens:");
10884 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10885 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010886 pw.print(" Exiting #"); pw.print(i);
10887 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 token.dump(pw, " ");
10889 }
10890 }
10891 if (mExitingAppTokens.size() > 0) {
10892 pw.println(" ");
10893 pw.println(" Exiting application tokens:");
10894 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10895 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010896 pw.print(" Exiting App #"); pw.print(i);
10897 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 token.dump(pw, " ");
10899 }
10900 }
10901 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010902 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10903 pw.print(" mLastFocus="); pw.println(mLastFocus);
10904 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10905 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
10906 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010907 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010908 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10909 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10910 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10911 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010912 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10913 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10914 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010915 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10916 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
10917 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
10918 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010919 if (mDimAnimator != null) {
10920 mDimAnimator.printTo(pw);
10921 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080010922 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010923 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010924 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070010925 pw.print(mInputMethodAnimLayerAdjustment);
10926 pw.print(" mWallpaperAnimLayerAdjustment=");
10927 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010928 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10929 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010930 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
10931 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010932 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
10933 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010934 pw.print(" mRotation="); pw.print(mRotation);
10935 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
10936 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
10937 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
10938 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10939 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
10940 pw.print(" mNextAppTransition=0x");
10941 pw.print(Integer.toHexString(mNextAppTransition));
10942 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070010943 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010944 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010945 if (mNextAppTransitionPackage != null) {
10946 pw.print(" mNextAppTransitionPackage=");
10947 pw.print(mNextAppTransitionPackage);
10948 pw.print(", mNextAppTransitionEnter=0x");
10949 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10950 pw.print(", mNextAppTransitionExit=0x");
10951 pw.print(Integer.toHexString(mNextAppTransitionExit));
10952 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010953 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
10954 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010955 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
10956 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
10957 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
10958 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010959 if (mOpeningApps.size() > 0) {
10960 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10961 }
10962 if (mClosingApps.size() > 0) {
10963 pw.print(" mClosingApps="); pw.println(mClosingApps);
10964 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010965 if (mToTopApps.size() > 0) {
10966 pw.print(" mToTopApps="); pw.println(mToTopApps);
10967 }
10968 if (mToBottomApps.size() > 0) {
10969 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
10970 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010971 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
10972 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 }
10974 }
10975
Jeff Brown349703e2010-06-22 01:27:15 -070010976 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010977 public void monitor() {
10978 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050010979 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010980 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010981
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010982 /**
10983 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010984 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010985 */
10986 private static class DimAnimator {
10987 Surface mDimSurface;
10988 boolean mDimShown = false;
10989 float mDimCurrentAlpha;
10990 float mDimTargetAlpha;
10991 float mDimDeltaPerMs;
10992 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070010993
10994 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010995
10996 DimAnimator (SurfaceSession session) {
10997 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010998 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010999 + mDimSurface + ": CREATE");
11000 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011001 mDimSurface = new Surface(session, 0,
11002 "DimSurface",
11003 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011004 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011005 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011006 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011007 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011008 }
11009 }
11010 }
11011
11012 /**
11013 * Show the dim surface.
11014 */
11015 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011016 if (!mDimShown) {
11017 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11018 dw + "x" + dh + ")");
11019 mDimShown = true;
11020 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011021 mLastDimWidth = dw;
11022 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011023 mDimSurface.setPosition(0, 0);
11024 mDimSurface.setSize(dw, dh);
11025 mDimSurface.show();
11026 } catch (RuntimeException e) {
11027 Slog.w(TAG, "Failure showing dim surface", e);
11028 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011029 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11030 mLastDimWidth = dw;
11031 mLastDimHeight = dh;
11032 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011033 }
11034 }
11035
11036 /**
11037 * Set's the dim surface's layer and update dim parameters that will be used in
11038 * {@link updateSurface} after all windows are examined.
11039 */
11040 void updateParameters(WindowState w, long currentTime) {
11041 mDimSurface.setLayer(w.mAnimLayer-1);
11042
11043 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011044 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011045 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011046 if (mDimTargetAlpha != target) {
11047 // If the desired dim level has changed, then
11048 // start an animation to it.
11049 mLastDimAnimTime = currentTime;
11050 long duration = (w.mAnimating && w.mAnimation != null)
11051 ? w.mAnimation.computeDurationHint()
11052 : DEFAULT_DIM_DURATION;
11053 if (target > mDimTargetAlpha) {
11054 // This is happening behind the activity UI,
11055 // so we can make it run a little longer to
11056 // give a stronger impression without disrupting
11057 // the user.
11058 duration *= DIM_DURATION_MULTIPLIER;
11059 }
11060 if (duration < 1) {
11061 // Don't divide by zero
11062 duration = 1;
11063 }
11064 mDimTargetAlpha = target;
11065 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11066 }
11067 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011068
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011069 /**
11070 * Updating the surface's alpha. Returns true if the animation continues, or returns
11071 * false when the animation is finished and the dim surface is hidden.
11072 */
11073 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11074 if (!dimming) {
11075 if (mDimTargetAlpha != 0) {
11076 mLastDimAnimTime = currentTime;
11077 mDimTargetAlpha = 0;
11078 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11079 }
11080 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011081
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011082 boolean animating = false;
11083 if (mLastDimAnimTime != 0) {
11084 mDimCurrentAlpha += mDimDeltaPerMs
11085 * (currentTime-mLastDimAnimTime);
11086 boolean more = true;
11087 if (displayFrozen) {
11088 // If the display is frozen, there is no reason to animate.
11089 more = false;
11090 } else if (mDimDeltaPerMs > 0) {
11091 if (mDimCurrentAlpha > mDimTargetAlpha) {
11092 more = false;
11093 }
11094 } else if (mDimDeltaPerMs < 0) {
11095 if (mDimCurrentAlpha < mDimTargetAlpha) {
11096 more = false;
11097 }
11098 } else {
11099 more = false;
11100 }
11101
11102 // Do we need to continue animating?
11103 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011104 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011105 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11106 mLastDimAnimTime = currentTime;
11107 mDimSurface.setAlpha(mDimCurrentAlpha);
11108 animating = true;
11109 } else {
11110 mDimCurrentAlpha = mDimTargetAlpha;
11111 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011112 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011113 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11114 mDimSurface.setAlpha(mDimCurrentAlpha);
11115 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011116 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011117 + ": HIDE");
11118 try {
11119 mDimSurface.hide();
11120 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011121 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011122 }
11123 mDimShown = false;
11124 }
11125 }
11126 }
11127 return animating;
11128 }
11129
11130 public void printTo(PrintWriter pw) {
11131 pw.print(" mDimShown="); pw.print(mDimShown);
11132 pw.print(" current="); pw.print(mDimCurrentAlpha);
11133 pw.print(" target="); pw.print(mDimTargetAlpha);
11134 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11135 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11136 }
11137 }
11138
11139 /**
11140 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11141 * This is used for opening/closing transition for apps in compatible mode.
11142 */
11143 private static class FadeInOutAnimation extends Animation {
11144 int mWidth;
11145 boolean mFadeIn;
11146
11147 public FadeInOutAnimation(boolean fadeIn) {
11148 setInterpolator(new AccelerateInterpolator());
11149 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11150 mFadeIn = fadeIn;
11151 }
11152
11153 @Override
11154 protected void applyTransformation(float interpolatedTime, Transformation t) {
11155 float x = interpolatedTime;
11156 if (!mFadeIn) {
11157 x = 1.0f - x; // reverse the interpolation for fade out
11158 }
11159 if (x < 0.5) {
11160 // move the window out of the screen.
11161 t.getMatrix().setTranslate(mWidth, 0);
11162 } else {
11163 t.getMatrix().setTranslate(0, 0);// show
11164 t.setAlpha((x - 0.5f) * 2);
11165 }
11166 }
11167
11168 @Override
11169 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11170 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11171 mWidth = width;
11172 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011173
11174 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011175 public int getZAdjustment() {
11176 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011177 }
11178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011179}